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
@@ -26,6 +26,7 @@ import { CaptureImageDialogComponent } from './custom-dialogs/capture-image-dial
/** Custom Services */
import { ClientsService } from '../clients.service';
import { LegalFormId } from '../models/legal-form.enum';
import { familyAllowed, nomineeAllowed } from '../utils/client-rules';
import {
MatCard,
MatCardHeader,
@@ -143,6 +144,21 @@ export class ClientsViewComponent implements OnInit {
clientImage: any;
clientTemplateData: any;
/** Constitution display name (entity clients only). Empty for individuals. */
get constitutionLabel(): string {
return this.clientViewData?.clientNonPersonDetails?.constitution?.name || '';
}
/** Whether the "Family Members" tab should appear. */
get showFamilyTab(): boolean {
return familyAllowed(this.clientViewData?.legalForm?.id, this.constitutionLabel);
}
/** Whether the "Nominees" tab should appear. */
get showNomineeTab(): boolean {
return nomineeAllowed(this.clientViewData?.legalForm?.id, this.constitutionLabel);
}
constructor() {
this.route.data.subscribe((data: { clientViewData: any; clientTemplateData: any; clientDatatables: any }) => {
this.clientViewData = data.clientViewData;