diff --git a/src/app/account-transfers/view-account-transfer/view-account-transfer.component.ts b/src/app/account-transfers/view-account-transfer/view-account-transfer.component.ts index b4642f4eb8..1553ad59a6 100644 --- a/src/app/account-transfers/view-account-transfer/view-account-transfer.component.ts +++ b/src/app/account-transfers/view-account-transfer/view-account-transfer.component.ts @@ -57,11 +57,11 @@ export class ViewAccountTransferComponent { } transferToClient(toClient: any): string { - return `/#/clients/${toClient.id}`; + return `/#/members/${toClient.id}`; } transferToAccount(toClient: any, toAccount: any): string { - return `/#/clients/${toClient.id}/savings-accounts/${toAccount.id}`; + return `/#/members/${toClient.id}/savings-accounts/${toAccount.id}`; } goBack(): void { diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c7db7a8627..be21dd9cba 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -33,7 +33,7 @@ const routes: Routes = [ loadChildren: () => import('./centers/centers.module').then((m) => m.CentersModule) }, { - path: 'clients', + path: 'members', loadChildren: () => import('./clients/clients.module').then((m) => m.ClientsModule) }, { diff --git a/src/app/clients/client-stepper/client-general-step/client-general-step.component.html b/src/app/clients/client-stepper/client-general-step/client-general-step.component.html index ba69c7b133..56e9febae4 100644 --- a/src/app/clients/client-stepper/client-general-step/client-general-step.component.html +++ b/src/app/clients/client-stepper/client-general-step/client-general-step.component.html @@ -8,7 +8,8 @@
- + + {{ 'labels.inputs.Office' | translate }} @for (office of officeOptions; track office) { @@ -25,7 +26,7 @@ } - + {{ 'labels.inputs.Legal Form' | translate }} @for (legalForm of legalFormOptions; track legalForm) { @@ -36,7 +37,7 @@ - + {{ 'labels.inputs.External Id' | translate }} @if (!externalNationalIdService.isLoading && externalNationalIdService.statusMessageKey) { @@ -55,7 +56,7 @@ @if (createClientForm.get('fullname')) { - + {{ 'labels.inputs.' + getDateLabel(createClientForm.value.legalFormId, ['Name', 'Entity Name']) | translate }} @@ -75,65 +76,62 @@ } - @if (createClientForm.get('firstname') || createClientForm.get('middlename') || createClientForm.get('lastname')) { -
- @if (createClientForm.get('firstname')) { - - {{ 'labels.inputs.First Name' | translate }} - - @if (createClientForm.controls.firstname.hasError('required')) { - - {{ 'labels.inputs.Client first name' | translate }} {{ 'labels.commons.is' | translate }} - {{ 'labels.commons.required' | translate }} - - } - @if (createClientForm.controls.firstname.hasError('pattern')) { - - {{ 'labels.inputs.Client first name' | translate }} - {{ 'labels.inputs.cannot' | translate }} - {{ 'labels.commons.begin with a special character or number' | translate }} - - } - + @if (createClientForm.get('firstname')) { + + {{ 'labels.inputs.First Name' | translate }} + + @if (createClientForm.controls.firstname.hasError('required')) { + + {{ 'labels.inputs.Client first name' | translate }} {{ 'labels.commons.is' | translate }} + {{ 'labels.commons.required' | translate }} + } - @if (createClientForm.get('middlename')) { - - {{ 'labels.inputs.Middle Name' | translate }} - - @if (createClientForm.controls.middlename.hasError('pattern')) { - - {{ 'labels.inputs.Client middle name' | translate }} - {{ 'labels.inputs.cannot' | translate }} - {{ 'labels.commons.begin with a special character or number' | translate }} - - } - + @if (createClientForm.controls.firstname.hasError('pattern')) { + + {{ 'labels.inputs.Client first name' | translate }} + {{ 'labels.inputs.cannot' | translate }} + {{ 'labels.commons.begin with a special character or number' | translate }} + } - @if (createClientForm.get('lastname')) { - - {{ 'labels.inputs.Last Name' | translate }} - - @if (createClientForm.controls.lastname.hasError('required')) { - - {{ 'labels.inputs.Client last name' | translate }} {{ 'labels.commons.is' | translate }} - {{ 'labels.commons.required' | translate }} - - } - @if (createClientForm.controls.lastname.hasError('pattern')) { - - {{ 'labels.inputs.Client last name' | translate }} - {{ 'labels.inputs.cannot' | translate }} - {{ 'labels.commons.begin with a special character or number' | translate }} - - } - + + } + + @if (createClientForm.get('middlename')) { + + {{ 'labels.inputs.Middle Name' | translate }} + + @if (createClientForm.controls.middlename.hasError('pattern')) { + + {{ 'labels.inputs.Client middle name' | translate }} + {{ 'labels.inputs.cannot' | translate }} + {{ 'labels.commons.begin with a special character or number' | translate }} + } -
+
} - + + @if (createClientForm.get('lastname')) { + + {{ 'labels.inputs.Last Name' | translate }} + + @if (createClientForm.controls.lastname.hasError('required')) { + + {{ 'labels.inputs.Client last name' | translate }} {{ 'labels.commons.is' | translate }} + {{ 'labels.commons.required' | translate }} + + } + @if (createClientForm.controls.lastname.hasError('pattern')) { + + {{ 'labels.inputs.Client last name' | translate }} + {{ 'labels.inputs.cannot' | translate }} + {{ 'labels.commons.begin with a special character or number' | translate }} + + } + + } - + {{ 'labels.inputs.' + getDateLabel(createClientForm.value.legalFormId, ['Date of Birth', 'Incorporation Date']) @@ -191,7 +189,7 @@ } @if (createClientForm.value.legalFormId === LegalFormId.PERSON) { - + {{ 'labels.inputs.Gender' | translate }} @for (gender of genderOptions; track gender) { @@ -203,7 +201,7 @@ } - + {{ 'labels.inputs.Staff' | translate }} @for (staff of staffOptions; track staff) { @@ -215,19 +213,20 @@ @if (createClientForm.value.legalFormId === LegalFormId.PERSON) { - + {{ 'labels.inputs.Is staff' | translate }}? } - + + {{ 'labels.inputs.Mobile No' | translate }} - + {{ 'labels.inputs.Email Address' | translate }} @if (createClientForm.controls.emailAddress.errors?.email) { @@ -237,7 +236,7 @@ } - + {{ 'labels.inputs.Client Type' | translate }} @for (clientType of clientTypeOptions; track clientType) { @@ -248,7 +247,7 @@ - + {{ 'labels.inputs.Client Classification' | translate }} @for (clientClassification of clientClassificationTypeOptions; track clientClassification) { @@ -259,7 +258,8 @@ - + + {{ 'labels.inputs.Submitted On' | translate }} -
- - + {{ 'labels.inputs.Active' | translate }}? @if (createClientForm.contains('activationDate')) { - + {{ 'labels.inputs.Activation Date' | translate }} } - + {{ 'labels.inputs.Open Savings Account' | translate }}? @if (createClientForm.contains('savingsProductId')) { - + {{ 'labels.inputs.Savings Product' | translate }} @for (product of savingProductOptions; track product) { diff --git a/src/app/clients/client-stepper/client-general-step/client-general-step.component.scss b/src/app/clients/client-stepper/client-general-step/client-general-step.component.scss index c70f269b73..5e52d94090 100644 --- a/src/app/clients/client-stepper/client-general-step/client-general-step.component.scss +++ b/src/app/clients/client-stepper/client-general-step/client-general-step.component.scss @@ -14,6 +14,18 @@ form { } } +.flex-10 { + flex: 0 0 10%; +} + +.flex-15 { + flex: 0 0 15%; +} + +.flex-22 { + flex: 0 0 22%; +} + mat-form-field { margin-bottom: 8px; } diff --git a/src/app/clients/clients-routing.module.ts b/src/app/clients/clients-routing.module.ts index aebcc36ac4..5ee0779e92 100644 --- a/src/app/clients/clients-routing.module.ts +++ b/src/app/clients/clients-routing.module.ts @@ -68,7 +68,7 @@ const routes: Routes = [ }, { path: 'create', - data: { title: 'Create Client', breadcrumb: 'Create Client', routeParamBreadcrumb: false }, + data: { title: 'Create Member', breadcrumb: 'Create Member', routeParamBreadcrumb: false }, component: CreateClientComponent, resolve: { clientAddressFieldConfig: ClientAddressFieldConfigurationResolver, @@ -78,7 +78,7 @@ const routes: Routes = [ { path: ':clientId', component: ClientsViewComponent, - data: { title: 'Clients View', routeParamBreadcrumb: 'clientId' }, + data: { title: 'Members View', routeParamBreadcrumb: 'clientId' }, resolve: { clientViewData: ClientViewResolver, clientTemplateData: ClientTemplateResolver, diff --git a/src/app/clients/clients-view/clients-view.component.ts b/src/app/clients/clients-view/clients-view.component.ts index 5dfdc4c134..e95076c8d7 100644 --- a/src/app/clients/clients-view/clients-view.component.ts +++ b/src/app/clients/clients-view/clients-view.component.ts @@ -270,7 +270,7 @@ export class ClientsViewComponent implements OnInit { */ reload() { const url: string = this.router.url; - this.router.navigateByUrl(`/clients`, { skipLocationChange: true }).then(() => this.router.navigate([url])); + this.router.navigateByUrl(`/members`, { skipLocationChange: true }).then(() => this.router.navigate([url])); } /** @@ -286,7 +286,7 @@ export class ClientsViewComponent implements OnInit { } if (response.delete) { this.clientsService.deleteClient(this.clientViewData.id).subscribe(() => { - this.router.navigate(['/clients'], { relativeTo: this.route }); + this.router.navigate(['/members'], { relativeTo: this.route }); }); } }); diff --git a/src/app/collaterals/view-collateral/view-collateral.component.html b/src/app/collaterals/view-collateral/view-collateral.component.html index 1efb8d7d49..971b2a5f94 100644 --- a/src/app/collaterals/view-collateral/view-collateral.component.html +++ b/src/app/collaterals/view-collateral/view-collateral.component.html @@ -69,7 +69,7 @@

{{ 'labels.heading.Transaction Details' | translate }}

+ --> diff --git a/src/app/core/authentication/authentication.service.ts b/src/app/core/authentication/authentication.service.ts index a256e92773..edb5dfac4b 100644 --- a/src/app/core/authentication/authentication.service.ts +++ b/src/app/core/authentication/authentication.service.ts @@ -66,7 +66,6 @@ export class AuthenticationService { */ private storage: Storage = sessionStorage; private credentials: Credentials; - private dialogShown = false; private authMode: AuthMode = AuthMode.Basic; /** Promise that resolves once the OIDC discovery document has been loaded. */ @@ -372,7 +371,6 @@ export class AuthenticationService { this.authenticationInterceptor.removeAuthorization(); this.setCredentials(); - this.resetDialog(); this.userLoggedIn$.next(false); if (this.authMode === AuthMode.OIDC) { @@ -481,18 +479,6 @@ export class AuthenticationService { return this.http.get('/twofactor'); } - showDialog() { - this.dialogShown = true; - } - - resetDialog() { - this.dialogShown = false; - } - - hasDialogBeenShown() { - return this.dialogShown; - } - /** * Requests OTP to be sent via the given delivery method. * @param {any} deliveryMethod Delivery method for the OTP. diff --git a/src/app/core/shell/sidenav/sidenav.component.html b/src/app/core/shell/sidenav/sidenav.component.html index 90ec61a93c..a750ccce97 100644 --- a/src/app/core/shell/sidenav/sidenav.component.html +++ b/src/app/core/shell/sidenav/sidenav.component.html @@ -15,7 +15,6 @@ -
- -
- - -
-
- -
-
- - - - - - - - - - - diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/charges-tab/charges-tab.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/charges-tab/charges-tab.component.ts index 04405d9282..434536cf78 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/charges-tab/charges-tab.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/charges-tab/charges-tab.component.ts @@ -303,7 +303,7 @@ export class ChargesTabComponent implements OnInit { const clientId = this.fixedDepositsAccountData.clientId; const url: string = this.router.url; this.router - .navigateByUrl(`/clients/${clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) + .navigateByUrl(`/members/${clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) .then(() => this.router.navigate([url])); } } diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts index a7971339c0..ff41497c31 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts @@ -149,7 +149,7 @@ export class FixedDepositAccountViewComponent implements OnInit { const clientId = this.fixedDepositsAccountData.clientId; const url: string = this.router.url; this.router - .navigateByUrl(`/clients/${clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) + .navigateByUrl(`/members/${clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) .then(() => this.router.navigate([url])); } diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/transactions-tab/transactions-tab.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/transactions-tab/transactions-tab.component.ts index ff15f2d2c0..ddcfcd8f2a 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/transactions-tab/transactions-tab.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/transactions-tab/transactions-tab.component.ts @@ -243,7 +243,7 @@ export class TransactionsTabComponent implements OnInit { reload() { const url: string = this.router.url; this.router - .navigateByUrl(`/clients/${this.clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) + .navigateByUrl(`/members/${this.clientId}/fixed-deposits-accounts`, { skipLocationChange: true }) .then(() => this.router.navigate([url])); } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/charges-tab/charges-tab.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/charges-tab/charges-tab.component.ts index bcb78acb21..504810d41e 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/charges-tab/charges-tab.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/charges-tab/charges-tab.component.ts @@ -259,7 +259,7 @@ export class ChargesTabComponent implements OnInit { const clientId = this.recurringDepositsAccountData.clientId; const url: string = this.router.url; this.router - .navigateByUrl(`/clients/${clientId}/recurring-deposits-accounts`, { skipLocationChange: true }) + .navigateByUrl(`/members/${clientId}/recurring-deposits-accounts`, { skipLocationChange: true }) .then(() => this.router.navigate([url])); } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts index 89a51929fa..e27c1d6df0 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts @@ -199,7 +199,7 @@ export class RecurringDepositsAccountViewComponent implements OnInit { const clientId = this.recurringDepositsAccountData.clientId; const url: string = this.router.url; this.router - .navigateByUrl(`/clients/${clientId}/recurring-deposits-accounts`, { skipLocationChange: true }) + .navigateByUrl(`/members/${clientId}/recurring-deposits-accounts`, { skipLocationChange: true }) .then(() => this.router.navigate([url])); } diff --git a/src/app/groups/groups-view/general-tab/general-tab.component.html b/src/app/groups/groups-view/general-tab/general-tab.component.html index c8557fdfa5..91f6b908df 100644 --- a/src/app/groups/groups-view/general-tab/general-tab.component.html +++ b/src/app/groups/groups-view/general-tab/general-tab.component.html @@ -63,7 +63,7 @@

{{ 'labels.heading.Client Members' | translate }}

diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index ed75382b6b..1d8ca49e64 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -27,7 +27,6 @@ import { startWith, map } from 'rxjs/operators'; /** Custom Imports. */ import { activities } from './activities'; -import { WarningDialogComponent } from './warning-dialog/warning-dialog.component'; /** Custom Services */ import { AuthenticationService } from '../core/authentication/authentication.service'; @@ -106,10 +105,6 @@ export class HomeComponent implements OnInit, AfterViewInit { this.username = credentials.username; this.tenant = this.tenantIdentifier(); this.setFilteredActivities(); - if (!this.authenticationService.hasDialogBeenShown()) { - this.dialog.open(WarningDialogComponent); - this.authenticationService.showDialog(); - } } /** diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts index 86c9f7b124..290a6b761d 100644 --- a/src/app/home/home.module.ts +++ b/src/app/home/home.module.ts @@ -19,7 +19,7 @@ import { PipesModule } from '../pipes/pipes.module'; import { HomeComponent } from './home.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { TranslateModule } from '@ngx-translate/core'; -import { WarningDialogComponent } from './warning-dialog/warning-dialog.component'; + import { SessionTimeoutDialogComponent } from './timeout-dialog/session-timeout-dialog.component'; /** @@ -36,7 +36,6 @@ import { SessionTimeoutDialogComponent } from './timeout-dialog/session-timeout- TranslateModule, HomeComponent, DashboardComponent, - WarningDialogComponent, SessionTimeoutDialogComponent ], providers: [] diff --git a/src/app/home/warning-dialog/warning-dialog.component.html b/src/app/home/warning-dialog/warning-dialog.component.html deleted file mode 100644 index 87001bc3b9..0000000000 --- a/src/app/home/warning-dialog/warning-dialog.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - -

{{ 'labels.text.' + title | translate }}

-{{ 'labels.text.Warning message' | translate }} - - - diff --git a/src/app/home/warning-dialog/warning-dialog.component.scss b/src/app/home/warning-dialog/warning-dialog.component.scss deleted file mode 100644 index af9f4c0753..0000000000 --- a/src/app/home/warning-dialog/warning-dialog.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Copyright since 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ diff --git a/src/app/home/warning-dialog/warning-dialog.component.ts b/src/app/home/warning-dialog/warning-dialog.component.ts deleted file mode 100644 index 158cdaaf13..0000000000 --- a/src/app/home/warning-dialog/warning-dialog.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright since 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; -import { - MatDialogRef, - MatDialogTitle, - MatDialogContent, - MatDialogActions, - MatDialogClose -} from '@angular/material/dialog'; -import { environment } from '../../../environments/environment'; -import { CdkScrollable } from '@angular/cdk/scrolling'; -import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; - -@Component({ - selector: 'mifosx-warning-dialog', - standalone: true, - templateUrl: './warning-dialog.component.html', - styleUrls: ['./warning-dialog.component.scss'], - imports: [ - ...STANDALONE_SHARED_IMPORTS, - MatDialogTitle, - CdkScrollable, - MatDialogContent, - MatDialogActions, - MatDialogClose - ], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class WarningDialogComponent { - dialogRef = inject>(MatDialogRef); - - title: string; - content: string; - buttonText: string; - - constructor() { - this.title = environment.warningDialog.title; - this.content = environment.warningDialog.content; - this.buttonText = environment.warningDialog.buttonText; - } -} diff --git a/src/app/keyboards-shortcut-config.ts b/src/app/keyboards-shortcut-config.ts index 20cb6cd103..1c00c62ef9 100644 --- a/src/app/keyboards-shortcut-config.ts +++ b/src/app/keyboards-shortcut-config.ts @@ -63,12 +63,12 @@ export class KeyboardShortcutsConfiguration { // }, // Create Client - ctrl + c { - title: 'Create Client', + title: 'Create Member', ctrlKey: false, shiftKey: false, altKey: true, key: 'c', - route: 'clients/create' + route: 'members/create' }, // Create Group - ctrl + g { diff --git a/src/app/loans/loans-view/loan-account-tab-base.component.ts b/src/app/loans/loans-view/loan-account-tab-base.component.ts index fd46e974e1..3865fbe0a0 100644 --- a/src/app/loans/loans-view/loan-account-tab-base.component.ts +++ b/src/app/loans/loans-view/loan-account-tab-base.component.ts @@ -21,7 +21,7 @@ export abstract class LoanAccountTabBaseComponent { protected reload() { const url: string = this.router.url.split('?')[0]; this.router - .navigateByUrl(`/clients`, { skipLocationChange: true }) + .navigateByUrl(`/members`, { skipLocationChange: true }) .then(() => this.router.navigate([url], { queryParams: { productType: this.loanProductService.productType.value } }) ); diff --git a/src/app/loans/loans-view/transactions/view-transaction/view-transaction.component.ts b/src/app/loans/loans-view/transactions/view-transaction/view-transaction.component.ts index 6bf2c7fda2..b952316fb3 100644 --- a/src/app/loans/loans-view/transactions/view-transaction/view-transaction.component.ts +++ b/src/app/loans/loans-view/transactions/view-transaction/view-transaction.component.ts @@ -374,7 +374,7 @@ export class ViewTransactionComponent extends LoanAccountActionsBaseComponent im } loanTransactionRelatedLink(transactionId: number) { - return `/#/clients/${this.clientId}/loans-accounts/${this.loanId}/transactions/${transactionId}`; + return `/#/members/${this.clientId}/loans-accounts/${this.loanId}/transactions/${transactionId}`; } loanTransactionColor(): string { diff --git a/src/app/login/login-form/login-form.component.html b/src/app/login/login-form/login-form.component.html index a8718705ab..ade271a7f8 100644 --- a/src/app/login/login-form/login-form.component.html +++ b/src/app/login/login-form/login-form.component.html @@ -85,7 +85,7 @@ variant="filled" type="submit" class="login-submit-button" - [disabled]="!loginForm.valid || loading" + [disabled]="loading" [fullWidth]="true" [label]="(loading ? 'labels.buttons.Signing in...' : 'labels.buttons.Login') | translate" > diff --git a/src/app/login/login-form/login-form.component.scss b/src/app/login/login-form/login-form.component.scss index 1b903ffbeb..3fc3f96d68 100644 --- a/src/app/login/login-form/login-form.component.scss +++ b/src/app/login/login-form/login-form.component.scss @@ -1,4 +1,4 @@ -/** +/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public @@ -6,22 +6,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/** - * Modern Material Design 3 Login Form Styles - */ +// ===== Colors ===== +$brand-blue: #1074b9; +$text-dark: #1e293b; +$text-muted: #64748b; +$input-bg: #f1f5f9; +$input-border: #e2e8f0; // ===== Main Form Container ===== -.modern-login-form { - width: 100%; - flex: 1; - display: flex; - flex-direction: column; -} - #login-form { display: flex; flex-direction: column; - gap: 0.5rem; + gap: 0.75rem; animation: slide-in 0.4s ease-out; flex: 1; } @@ -38,46 +34,35 @@ width: 100%; margin-bottom: 0; - // Apply same styling as login fields .mat-mdc-text-field-wrapper { - border-radius: 12px 12px 0 0; + background: $input-bg; + border-radius: 10px; + border: 1px solid $input-border; } .mat-mdc-form-field-focus-overlay { - border-radius: 12px 12px 0 0; - background-color: var(--md-sys-color-on-surface, #1a1c1e); - opacity: 0.04; - } - - &.mat-focused { - .mat-mdc-form-field-focus-overlay { - opacity: 0.12; - } + display: none; } + .mdc-line-ripple::before, .mdc-line-ripple::after { - border-bottom-color: var(--md-sys-color-primary, #1074b9); + border-bottom: none; } .mat-mdc-select { - font-size: 1rem; + font-size: 0.95rem; font-weight: 400; - color: var(--md-sys-color-on-surface, #1a1c1e); + color: $text-dark; } .mat-mdc-floating-label { - font-size: 1rem; - color: var(--md-sys-color-on-surface-variant, #44474e); + font-size: 0.95rem; + color: $text-muted; } .mat-mdc-form-field-icon-prefix { padding: 0 0.75rem 0 0.5rem; - color: var(--md-sys-color-on-surface-variant, #44474e); - - fa-icon { - font-size: 1.25rem; - opacity: 0.7; - } + color: $text-muted; } } @@ -93,93 +78,82 @@ margin-bottom: 0; ::ng-deep { - // Field container .mat-mdc-text-field-wrapper { - border-radius: 12px 12px 0 0; + background: $input-bg !important; + border-radius: 10px !important; + border: 1px solid $input-border !important; + transition: border-color 0.2s ease; } - // Focus overlay - .mat-mdc-form-field-focus-overlay { - border-radius: 12px 12px 0 0; - background-color: var(--md-sys-color-on-surface, #1a1c1e); - opacity: 0.04; + &.mat-focused .mat-mdc-text-field-wrapper { + border-color: $brand-blue !important; } - // Focus state - &.mat-focused { - .mat-mdc-form-field-focus-overlay { - opacity: 0.12; - } + .mat-mdc-form-field-focus-overlay { + display: none !important; } - // Bottom indicator line + .mdc-line-ripple::before, .mdc-line-ripple::after { - border-bottom-color: var(--md-sys-color-primary, #1074b9); + border-bottom: none !important; } - // Input field .mat-mdc-input-element { - font-size: 1rem; + font-size: 0.95rem; font-weight: 400; - color: var(--md-sys-color-on-surface, #1a1c1e); + color: $text-dark; padding: 0.875rem 0; margin-left: 0; &::placeholder { - color: var(--md-sys-color-on-surface-variant, #44474e); - opacity: 0.6; + color: #94a3b8; + opacity: 1; } } - // Label .mat-mdc-floating-label { - font-size: 1rem; - color: var(--md-sys-color-on-surface-variant, #44474e); + font-size: 0.95rem; + color: $text-muted; left: 0 !important; } - // Prefix icon .mat-mdc-form-field-icon-prefix { padding: 0 0.75rem 0 0.5rem; - color: var(--md-sys-color-on-surface-variant, #44474e); + color: $text-muted; - fa-icon { - font-size: 1.25rem; - opacity: 0.7; + mifosx-m3-icon, + mat-icon { + color: $text-muted; } } - // Form field infix - align label with input .mat-mdc-form-field-infix { padding-left: 0; } - // Suffix button (password toggle) .mat-mdc-form-field-icon-suffix { button { background: transparent; border: none; - color: var(--md-sys-color-on-surface-variant, #44474e); - transition: all 0.2s ease; + color: $text-muted; + transition: color 0.2s ease; + + &:hover { + color: $text-dark; + } } } - // Error state &.mat-form-field-invalid { - .mdc-line-ripple::after { - border-bottom-color: var(--md-sys-color-error, #ba1a1a); - } - - .mat-mdc-form-field-icon-prefix fa-icon { - color: var(--md-sys-color-error, #ba1a1a); + .mat-mdc-text-field-wrapper { + border-color: #dc2626 !important; } } - // Error message .mat-mdc-form-field-error { font-size: 0.75rem; margin-top: 0.25rem; - color: var(--md-sys-color-error, #ba1a1a); + color: #dc2626; } } } @@ -188,11 +162,11 @@ .login-progress { height: 3px; border-radius: 4px; - margin: -0.5rem 0 0.5rem; + margin: -0.25rem 0 0.5rem; ::ng-deep { .mdc-linear-progress__bar-inner { - border-color: var(--md-sys-color-primary, #1074b9); + border-color: $brand-blue; } } } @@ -200,13 +174,18 @@ // ===== Submit Button ===== .login-submit-button { min-height: 48px; - color: var(--md-sys-color-on-surface-variant, #44474e); - margin-top: 0.5rem; + color: #fff; + margin-top: 0.75rem; ::ng-deep md-filled-button { - font-size: 1rem; - font-weight: 500; - letter-spacing: 0.01em; + font-size: 0.95rem; + font-weight: 600; + letter-spacing: 0.02em; + + --md-filled-button-container-color: #{$brand-blue}; + --md-filled-button-label-text-color: #fff; + + border-radius: 10px; } .button-spinner { @@ -233,7 +212,7 @@ .oidc-description { font-size: 0.95rem; - color: var(--md-sys-color-on-surface-variant, #44474e); + color: $text-muted; margin: 0; line-height: 1.5; } @@ -250,19 +229,19 @@ align-items: center; gap: 1rem; padding: 2rem; - background: var(--md-sys-color-primary-container, #d1e4ff); - border-radius: 16px; + background: #dbeafe; + border-radius: 12px; .success-icon { font-size: 3rem; - color: var(--md-sys-color-primary, #1074b9); + color: $brand-blue; } h3 { margin: 0; font-size: 1.25rem; font-weight: 600; - color: var(--md-sys-color-on-primary-container, #001d36); + color: $text-dark; } } @@ -279,9 +258,9 @@ .protected-data { padding: 1rem; - background: var(--md-sys-color-surface-container, #f3f3f3); + background: $input-bg; border-radius: 12px; - border: 1px solid var(--md-sys-color-outline-variant, #c4c6d0); + border: 1px solid $input-border; max-height: 300px; overflow: auto; @@ -289,28 +268,32 @@ margin: 0; font-size: 0.875rem; font-family: 'Courier New', monospace; - color: var(--md-sys-color-on-surface, #1a1c1e); + color: $text-dark; white-space: pre-wrap; overflow-wrap: break-word; } } -// ===== Dark Theme Support ===== +// ===== Dark Theme ===== :host-context(.dark-theme) { - // Tenant selector dark theme ::ng-deep .tenant-section { mifosx-tenant-selector { #tenant-selector { + .mat-mdc-text-field-wrapper { + background: #2a2a2a; + border-color: #444; + } + .mat-mdc-select { - color: var(--md-sys-color-on-surface, #e2e2e5); + color: #e2e2e5; } .mat-mdc-floating-label { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #c4c6d0; } .mat-mdc-form-field-icon-prefix { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #c4c6d0; } } } @@ -318,91 +301,87 @@ .login-field { ::ng-deep { + .mat-mdc-text-field-wrapper { + background: #2a2a2a !important; + border-color: #444 !important; + } + .mat-mdc-input-element { - color: var(--md-sys-color-on-surface, #e2e2e5); + color: #e2e2e5; &::placeholder { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #888; } } .mat-mdc-floating-label { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #c4c6d0; } .mat-mdc-form-field-icon-prefix { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #c4c6d0; + + mifosx-m3-icon, + mat-icon { + color: #c4c6d0; + } } .mat-mdc-form-field-icon-suffix button { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); + color: #c4c6d0; } } } - .oidc-description { - color: var(--md-sys-color-on-surface-variant, #c4c6d0); - } - .welcome-message { - background: var(--md-sys-color-primary-container, #003a6b); + background: #003a6b; .success-icon { - color: var(--md-sys-color-primary, #5ba2ec); + color: #5ba2ec; } h3 { - color: var(--md-sys-color-on-primary-container, #d1e4ff); + color: #d1e4ff; } } .protected-data { - background: var(--md-sys-color-surface-container, #2c2f36); - border-color: var(--md-sys-color-outline-variant, #44474e); + background: #2c2f36; + border-color: #44474e; pre { - color: var(--md-sys-color-on-surface, #e2e2e5); + color: #e2e2e5; } } } -// ===== Responsive Design ===== +// ===== Responsive ===== /* stylelint-disable-next-line media-feature-range-notation -- Safari compatibility */ @media (max-width: 768px) { #login-form { - gap: 0.25rem; - } - - .login-field { - margin-bottom: 0; + gap: 0.5rem; } .login-submit-button { margin-top: 0.5rem; } - - .login-actions { - margin-top: 0.5rem; - } } /* stylelint-disable-next-line media-feature-range-notation -- Safari compatibility */ @media (max-width: 480px) { #login-form { - gap: 0.15rem; + gap: 0.35rem; } .login-field { - margin-bottom: 0; - ::ng-deep { .mat-mdc-input-element { - font-size: 0.95rem; + font-size: 0.9rem; padding: 0.65rem 0.5rem; } .mat-mdc-floating-label { - font-size: 0.9rem; + font-size: 0.85rem; } .mat-mdc-form-field-icon-prefix { diff --git a/src/app/login/login-form/login-form.component.ts b/src/app/login/login-form/login-form.component.ts index 69349c6ed0..78ab14eaad 100644 --- a/src/app/login/login-form/login-form.component.ts +++ b/src/app/login/login-form/login-form.component.ts @@ -72,6 +72,10 @@ export class LoginFormComponent implements OnInit { * Authenticates the user if the credentials are valid. */ login() { + this.loginForm.markAllAsTouched(); + if (this.loginForm.invalid) { + return; + } this.loading = true; this.loginForm.disable(); this.authenticationService diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index c056c71655..b9bd9cf99d 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -5,78 +5,54 @@ License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. --> -