feat: KYC re-verify UX, family/nominee tab gating, savings dialogs, cfcfrms shell

- KYC tab: fix Verify (PAN) and Send OTP (Aadhaar) being disabled in edit mode;
  unmask Aadhaar input and show on-file masked value as hint; resolve kycId
  from id/kycId/resourceId fallbacks.
- Client stepper/view: add familyAllowed / nomineeAllowed predicates +
  CanActivate route guards. Family tab hidden for non-individuals, Nominee
  tab hidden for non-proprietor entities. Family-members step accepts a
  nomineeOnly input for proprietorship clients. Add/Edit/Delete buttons
  inside family-members and nominee tabs gated by canAdd.
- cfcfrms: add cfcfrms-shell wrapper, restyle complaint/fraud/mule/escalate
  pages and dashboard.
- Savings: identity-verify and transaction-confirm dialogs, manage / activate
  / add-charge flows, account preview styling.
- Tasks, core shell, account-nominees, icons: minor style and behaviour
  updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-05-21 18:49:43 +05:30
co-authored by Claude Opus 4.7
parent bf3e26a0d0
commit b149fef72e
99 changed files with 8575 additions and 2574 deletions
@@ -15,27 +15,24 @@ import { FormGroup } from '@angular/forms';
import { SavingsAccountDetailsStepComponent } from '../savings-account-stepper/savings-account-details-step/savings-account-details-step.component';
import { SavingsAccountCurrencyStepComponent } from '../savings-account-stepper/savings-account-currency-step/savings-account-currency-step.component';
import { SavingsAccountDigitalStepComponent } from '../savings-account-stepper/savings-account-digital-step/savings-account-digital-step.component';
import { SavingsAccountSettingsStepComponent } from '../savings-account-stepper/savings-account-settings-step/savings-account-settings-step.component';
/** Custom Services */
import { SavingsService } from '../savings.service';
import { SettingsService } from 'app/settings/settings.service';
import { Dates } from 'app/core/utils/dates';
import { AlertService } from 'app/core/alert/alert.service';
import {
MatStepper,
MatStepperIcon,
MatStep,
MatStepLabel,
MatStepperNext,
MatStepperPrevious
} from '@angular/material/stepper';
import { MatTabsModule } from '@angular/material/tabs';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { SavingsAccountPreviewStepComponent } from '../savings-account-stepper/savings-account-preview-step/savings-account-preview-step.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
* Create Savings Account Component
*
* Wizard-tab UI: Product → Currency → Digital → Preview. Tabs 2-4 are
* disabled until a product is picked on Tab 1 (matches the prior stepper
* gate that only rendered later steps once `savingsAccountProductTemplate`
* was set).
*/
@Component({
selector: 'mifosx-create-savings-account',
@@ -43,13 +40,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
styleUrls: ['./create-savings-account.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
MatStepper,
MatStepperIcon,
MatStepperNext,
MatStepperPrevious,
MatTabsModule,
FaIconComponent,
MatStep,
MatStepLabel,
SavingsAccountDetailsStepComponent,
SavingsAccountCurrencyStepComponent,
SavingsAccountDigitalStepComponent,
@@ -68,6 +60,10 @@ export class CreateSavingsAccountComponent {
savingsAccountTemplate: any;
/** Savings Account Product Template */
savingsAccountProductTemplate: any;
/** Currently visible wizard tab (0-indexed). */
selectedTabIndex = 0;
/** Total wizard tabs — Product, Currency, Digital, Preview. */
private readonly totalTabs = 4;
@ViewChild(SavingsAccountDetailsStepComponent, { static: true })
savingsAccountDetailsStep: SavingsAccountDetailsStepComponent;
@@ -88,6 +84,18 @@ export class CreateSavingsAccountComponent {
this.savingsAccountProductTemplate = $event;
}
next(): void {
if (this.selectedTabIndex < this.totalTabs - 1) {
this.selectedTabIndex += 1;
}
}
prev(): void {
if (this.selectedTabIndex > 0) {
this.selectedTabIndex -= 1;
}
}
get savingsAccountDetailsForm() {
return this.savingsAccountDetailsStep.savingsAccountDetailsForm;
}