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,145 @@
/**
* 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 { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { MatDialogModule, MatDialog } from '@angular/material/dialog';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { TranslateModule } from '@ngx-translate/core';
import { CfcfrmsService } from '../cfcfrms.service';
import { ConfirmDialogComponent } from '../components/confirm-dialog/confirm-dialog.component';
@Component({
selector: 'cfcfrms-report-suspect',
standalone: true,
templateUrl: './report-suspect.component.html',
styleUrls: ['./report-suspect.component.scss'],
imports: [
CommonModule,
ReactiveFormsModule,
MatCardModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatSelectModule,
MatDatepickerModule,
MatProgressSpinnerModule,
MatSnackBarModule,
MatDialogModule,
FaIconComponent,
TranslateModule
]
})
export class ReportSuspectComponent {
private fb = inject(FormBuilder);
private service = inject(CfcfrmsService);
private snackBar = inject(MatSnackBar);
private dialog = inject(MatDialog);
form: FormGroup = this.fb.group({
accountNumber: [
'',
[
Validators.required,
Validators.minLength(8)
]
],
accountName: [
'',
Validators.required
],
bankIfsc: [
'LINC0000001',
[
Validators.required,
Validators.pattern(/^[A-Z]{4}0[A-Z0-9]{6}$/)
]
],
suspicionReason: [
'',
Validators.required
],
detectedBy: [
'',
Validators.required
],
detectedOn: [
'',
Validators.required
],
linkedTransactions: [''],
remarks: ['']
});
isSubmitting = false;
result: any = null;
suspicionReasons = [
'Unusual transaction pattern',
'Multiple fraud complaints linked',
'High-value transactions to unknown beneficiaries',
'Account used as pass-through',
'KYC document mismatch',
'Tip-off from law enforcement',
'Internal fraud detection system alert',
'Other'
];
onSubmit(): void {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
data: { title: 'Confirm Report', message: 'Are you sure you want to report this suspect account to I4C?' }
});
dialogRef.afterClosed().subscribe((confirmed) => {
if (!confirmed) return;
this.isSubmitting = true;
const val = this.form.value;
const payload = {
...val,
detectedOn: new Date(val.detectedOn).toISOString(),
linkedTransactions: val.linkedTransactions
? val.linkedTransactions
.split(',')
.map((s: string) => s.trim())
.filter(Boolean)
: []
};
this.service.reportSuspect(payload).subscribe({
next: (res) => {
this.result = res;
this.isSubmitting = false;
this.snackBar.open('Suspect account reported successfully', 'OK', { duration: 4000 });
},
error: () => {
this.isSubmitting = false;
this.snackBar.open('Failed to report suspect account', 'OK', { duration: 4000 });
}
});
});
}
resetForm(): void {
this.form.reset({ bankIfsc: 'LINC0000001' });
this.result = null;
}
}