feat: add CFCFRMS module, bank menus, mock backend, and dashboard redesign

- CFCFRMS cyber fraud complaint management with dashboard, complaints,
  escalation, report suspect/mule/fraud txn, FMR submission, CFR lookup
- Mock HTTP interceptor with 20 dummy complaints and all endpoints
- Simulator service for I4C/MHA integration testing
- 3-row menu bar with 22 items (7+8+8 layout)
- Mega menus for General Ledger, Sub Ledger, Deposits, Share, Others,
  HRM, RBI with search and grouped columns
- Dropdowns for Cashier, Clearing, NPA, CKYC, Advances, Letter Mgmt,
  Insurance, Digital
- Dashboard redesign with regulatory, financial health, deposits,
  risk/NPA sections using static banking data
- All translations added to en-US.json
- FontAwesome icons registered for all new menu items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-18 18:05:43 +05:30
co-authored by Claude Opus 4.6
parent 0a32d7135e
commit b3a4cce0cf
55 changed files with 9667 additions and 298 deletions
@@ -0,0 +1,61 @@
/**
* 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 { Component, Inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
import { MatButtonModule } from '@angular/material/button';
export interface ConfirmDialogData {
title: string;
message: string;
confirmText?: string;
cancelText?: string;
}
@Component({
selector: 'cfcfrms-confirm-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
MatButtonModule
],
template: `
<h2 mat-dialog-title>{{ data.title }}</h2>
<mat-dialog-content>
<p>{{ data.message }}</p>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="onCancel()">{{ data.cancelText || 'Cancel' }}</button>
<button mat-raised-button color="primary" (click)="onConfirm()">{{ data.confirmText || 'Confirm' }}</button>
</mat-dialog-actions>
`,
styles: [
`
p {
margin: 8px 0;
font-size: 14px;
}
`
]
})
export class ConfirmDialogComponent {
constructor(
public dialogRef: MatDialogRef<ConfirmDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: ConfirmDialogData
) {}
onCancel(): void {
this.dialogRef.close(false);
}
onConfirm(): void {
this.dialogRef.close(true);
}
}
@@ -0,0 +1,81 @@
/**
* 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 { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ComplaintStatus } from '../../models/cfcfrms.models';
@Component({
selector: 'cfcfrms-status-badge',
standalone: true,
imports: [CommonModule],
template: `
<span class="status-badge" [ngClass]="'status-' + (status | lowercase)">
{{ statusLabel }}
</span>
`,
styles: [
`
.status-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
white-space: nowrap;
}
.status-received {
background: #dbeafe;
color: #1e40af;
}
.status-under_review {
background: #fef3c7;
color: #92400e;
}
.status-lien_marked {
background: #fef9c3;
color: #854d0e;
}
.status-debit_frozen {
background: #fee2e2;
color: #991b1b;
}
.status-funds_moved {
background: #ede9fe;
color: #5b21b6;
}
.status-resolved {
background: #d1fae5;
color: #065f46;
}
.status-rejected {
background: #f3f4f6;
color: #374151;
}
`
]
})
export class StatusBadgeComponent {
@Input() status: ComplaintStatus;
private readonly labels: Record<ComplaintStatus, string> = {
RECEIVED: 'Received',
UNDER_REVIEW: 'Under Review',
LIEN_MARKED: 'Lien Marked',
DEBIT_FROZEN: 'Debit Frozen',
FUNDS_MOVED: 'Funds Moved',
RESOLVED: 'Resolved',
REJECTED: 'Rejected'
};
get statusLabel(): string {
return this.labels[this.status] || this.status;
}
}