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
@@ -1024,8 +1024,8 @@
}
}
<!-- Family Members (Individual only) -->
@if (client?.legalFormId !== 2) {
<!-- Family Members — hidden when client isn't eligible (entities other than proprietorship). -->
@if (showFamilyPreview) {
<div class="info-card">
<div class="card-header">
<fa-icon icon="users" class="card-icon"></fa-icon>
@@ -24,6 +24,7 @@ import { DateFormatPipe } from '../../../pipes/date-format.pipe';
import { YesnoPipe } from '../../../pipes/yesno.pipe';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { LegalFormId } from 'app/clients/models/legal-form.enum';
import { familyAllowed, nomineeAllowed } from 'app/clients/utils/client-rules';
/**
* Client Preview Step Component
@@ -69,6 +70,11 @@ export class ClientPreviewStepComponent {
@Input() nominees: any[] = [];
/** Family members from family step */
@Input() familyMembers: any[] = [];
/**
* Constitution display name for entity clients — drives the proprietorship-only
* nominee rule so the preview matches what's eligible elsewhere.
*/
@Input() constitutionLabel: string = '';
/** Marital Status ID from general step */
@Input() maritalStatusId: number | null = null;
/** Marital Status Options */
@@ -99,6 +105,14 @@ export class ClientPreviewStepComponent {
/** Form submission event */
@Output() submitEvent = new EventEmitter();
get showFamilyPreview(): boolean {
return familyAllowed(this.client?.legalFormId, this.constitutionLabel);
}
get showNomineePreview(): boolean {
return nomineeAllowed(this.client?.legalFormId, this.constitutionLabel);
}
/** Expose enum to template */
readonly LegalFormId = LegalFormId;