feat: complete UI redesign — client creation tabs, footer, home page, CIF & occupation fields

- Client creation: replaced vertical stepper with 3-tab layout (General, KYC & Nominee, Preview)
- All form fields redesigned with appearance="outline" and section grouping
- Preview tab with profile card, info tables, KYC details, family members
- Footer redesigned: security bar, LincShield certifications, regulatory & legal, quick navigation, support & contact, LincPay branding
- Home page redesigned: welcome banner, quick action cards, info row
- Client view header redesigned: ID chips row (Account No, CIF Number, External Id), 4-column details grid
- Added CIF Number column to clients list table
- Added CIF Number display to client view sidebar and personal data tab
- Added occupationCategoryId and occupationId dropdowns to client creation form
- Added occupation fields to client view sidebar, personal data tab, and preview
- Added 51+ missing translation keys to en-US.json
- Toolbar: added Last login chip
- Registered faUserPlus icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-20 19:19:47 +05:30
co-authored by Claude Opus 4.6
parent b3a4cce0cf
commit 7b1f2e8ad7
81 changed files with 8384 additions and 3923 deletions
+28 -3
View File
@@ -9,6 +9,7 @@
/** Angular Imports */
import { Component, OnInit, OnDestroy, inject } from '@angular/core';
import { Router } from '@angular/router';
import { trigger, transition, style, animate } from '@angular/animations';
/** rxjs Imports */
@@ -56,6 +57,23 @@ import { VersionService } from '../system/version.service';
selector: 'mifosx-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
animations: [
trigger('settingsAnimation', [
transition(':enter', [
style({ opacity: 0, transform: 'translateY(-10px) scale(0.95)' }),
animate('200ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0) scale(1)' }))
]),
transition(':leave', [
animate('150ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateY(-10px) scale(0.95)' }))
])
]),
trigger('cardAnimation', [
transition(':enter', [
style({ opacity: 0, transform: 'translateY(30px) scale(0.96)' }),
animate('600ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0) scale(1)' }))
])
])
],
imports: [
...STANDALONE_SHARED_IMPORTS,
LanguageSelectorComponent,
@@ -100,13 +118,16 @@ export class LoginComponent implements OnInit, OnDestroy {
return tenant.charAt(0).toUpperCase() + tenant.slice(1).toLowerCase();
}
/** Whether the settings panel popup is open */
settingsPanelOpen = false;
/** True if password requires a reset. */
resetPassword = false;
/** True if user requires two factor authentication. */
twoFactorAuthenticationRequired = false;
/** Subscription to alerts. */
alert$: Subscription;
logoPath = 'assets/images/default_home.png';
logoPath = 'assets/images/cbsnexora-logo.png';
logoPathDark = 'assets/images/white-mifos.png';
/** Subscription to theme changes. */
theme$: Subscription;
@@ -188,6 +209,10 @@ export class LoginComponent implements OnInit, OnDestroy {
}
}
toggleSettingsPanel(): void {
this.settingsPanelOpen = !this.settingsPanelOpen;
}
reloadSettings(): void {
this.settingsService.setTenantIdentifier('');
this.settingsService.setTenantIdentifier(environment.fineractPlatformTenantId || 'default');
@@ -225,7 +250,7 @@ export class LoginComponent implements OnInit, OnDestroy {
if (environment.tenantLogoUrl && environment.tenantLogoUrl.trim() !== '') {
this.logoPath = environment.tenantLogoUrl;
} else {
this.logoPath = isTenantSpecific ? `assets/images/${tenant}_home.png` : 'assets/images/default_home.png';
this.logoPath = isTenantSpecific ? `assets/images/${tenant}_home.png` : 'assets/images/cbsnexora-logo.png';
}
// Set dark mode logo (env override takes priority)
@@ -237,7 +262,7 @@ export class LoginComponent implements OnInit, OnDestroy {
}
onLogoError(): void {
this.logoPath = 'assets/images/default_home.png';
this.logoPath = 'assets/images/cbsnexora-logo.png';
}
onLogoErrorDark(): void {