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:
co-authored by
Claude Opus 4.7
parent
bf3e26a0d0
commit
b149fef72e
@@ -0,0 +1,99 @@
|
||||
<!--
|
||||
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/.
|
||||
-->
|
||||
|
||||
<div class="cfc-container">
|
||||
<!-- Hero header -->
|
||||
<div class="cfc-header">
|
||||
<div class="cfc-header__left">
|
||||
<fa-icon icon="user-shield" class="cfc-header__icon"></fa-icon>
|
||||
<div>
|
||||
<h2 class="cfc-header__title">CFCFRMS</h2>
|
||||
<div class="cfc-header__sub">
|
||||
Cyber Fraud Complaint Management & Reporting — track complaints, escalate, and report suspect / mule
|
||||
/ fraud transactions.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pill-style tab navigation -->
|
||||
<nav mat-tab-nav-bar class="cfc-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab"
|
||||
[routerLink]="['./dashboard']"
|
||||
routerLinkActive
|
||||
#dashboard="routerLinkActive"
|
||||
[active]="dashboard.isActive"
|
||||
>
|
||||
<fa-icon icon="chart-line" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab"
|
||||
[routerLink]="['./complaints']"
|
||||
routerLinkActive
|
||||
#complaints="routerLinkActive"
|
||||
[active]="complaints.isActive"
|
||||
>
|
||||
<fa-icon icon="list-alt" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Complaints</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab"
|
||||
[routerLink]="['./escalate']"
|
||||
routerLinkActive
|
||||
#escalate="routerLinkActive"
|
||||
[active]="escalate.isActive"
|
||||
>
|
||||
<fa-icon icon="arrow-up" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Escalate</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab cfc-tab--danger"
|
||||
[routerLink]="['./report-suspect']"
|
||||
routerLinkActive
|
||||
#suspect="routerLinkActive"
|
||||
[active]="suspect.isActive"
|
||||
>
|
||||
<fa-icon icon="user-slash" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Report Suspect</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab cfc-tab--danger"
|
||||
[routerLink]="['./report-mule']"
|
||||
routerLinkActive
|
||||
#mule="routerLinkActive"
|
||||
[active]="mule.isActive"
|
||||
>
|
||||
<fa-icon icon="ban" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Report Mule</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cfc-tab cfc-tab--danger"
|
||||
[routerLink]="['./report-fraud-txn']"
|
||||
routerLinkActive
|
||||
#fraud="routerLinkActive"
|
||||
[active]="fraud.isActive"
|
||||
>
|
||||
<fa-icon icon="exclamation-triangle" class="cfc-tab__ic"></fa-icon>
|
||||
<span>Report Fraud Txn</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<mat-tab-nav-panel #tabPanel>
|
||||
<div class="cfc-body">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-tab-nav-panel>
|
||||
</div>
|
||||
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
$navy: #0d1b2a;
|
||||
$blue: #1e88e5;
|
||||
$blue-d: #1e40af;
|
||||
$indigo: #4f46e5;
|
||||
$red: #dc2626;
|
||||
$red-d: #991b1b;
|
||||
|
||||
.cfc-container {
|
||||
padding: 20px 24px;
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.cfc-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, $blue 0%, $indigo 100%);
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
box-shadow: 0 2px 8px rgb(29 78 216 / 25%);
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: $navy;
|
||||
line-height: 1.1;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
&__sub {
|
||||
margin-top: 2px;
|
||||
font-size: 12.5px;
|
||||
color: #64748b;
|
||||
max-width: 720px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pill-style tab navigation */
|
||||
.cfc-tabs {
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 14px;
|
||||
padding: 6px;
|
||||
box-shadow: 0 1px 3px rgb(15 23 42 / 4%);
|
||||
overflow: hidden;
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-tab-link-container {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab-links {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.mdc-tab-indicator__content--underline,
|
||||
.mat-mdc-tab-header-pagination-controls-enabled .mdc-tab-indicator__content--underline {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cfc-tab {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
height: 38px !important;
|
||||
min-width: 0 !important;
|
||||
padding: 0 18px !important;
|
||||
border-radius: 10px !important;
|
||||
font-family: Inter, 'DM Sans', Roboto, sans-serif !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 600 !important;
|
||||
letter-spacing: 0.01em !important;
|
||||
color: #64748b !important;
|
||||
background: transparent !important;
|
||||
transition: all 0.15s ease;
|
||||
white-space: nowrap;
|
||||
border: 1px solid transparent !important;
|
||||
opacity: 1 !important;
|
||||
|
||||
&__ic {
|
||||
font-size: 13px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&:hover:not(.mdc-tab--active) {
|
||||
background: #f1f5f9 !important;
|
||||
color: $navy !important;
|
||||
}
|
||||
|
||||
&.mdc-tab--active,
|
||||
&.mat-mdc-tab-link-active {
|
||||
background: linear-gradient(135deg, $blue 0%, $blue-d 100%) !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 2px 6px -1px rgb(30 64 175 / 35%);
|
||||
border-color: $blue-d !important;
|
||||
|
||||
::ng-deep .mdc-tab__text-label,
|
||||
::ng-deep .mat-mdc-tab-link-content,
|
||||
::ng-deep span,
|
||||
.cfc-tab__ic {
|
||||
color: #fff !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Danger-flavour tabs (the three reporting tabs) glow red when active so
|
||||
users can see at a glance that they're on a high-impact submission flow. */
|
||||
&--danger {
|
||||
&.mdc-tab--active,
|
||||
&.mat-mdc-tab-link-active {
|
||||
background: linear-gradient(135deg, $red 0%, $red-d 100%) !important;
|
||||
box-shadow: 0 2px 6px -1px rgb(153 27 27 / 40%);
|
||||
border-color: $red-d !important;
|
||||
}
|
||||
|
||||
&:hover:not(.mdc-tab--active) {
|
||||
background: #fef2f2 !important;
|
||||
color: $red-d !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cfc-body {
|
||||
/* Sub-pages no longer carry their own page-header (the hero above already
|
||||
does that). Add a little breathing room and let their content cards
|
||||
stand on their own. */
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (width <= 768px) {
|
||||
.cfc-tabs {
|
||||
overflow-x: auto;
|
||||
|
||||
::ng-deep .mat-mdc-tab-links {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.cfc-tab {
|
||||
padding: 0 14px !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 } from '@angular/core';
|
||||
import { MatTabNav, MatTabLink, MatTabNavPanel } from '@angular/material/tabs';
|
||||
import { RouterLinkActive, RouterLink, RouterOutlet } from '@angular/router';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
* CFCFRMS Shell — single landing page that exposes the full Cyber Fraud
|
||||
* Complaint Management workflow (Dashboard, Complaints, Escalate, Suspect /
|
||||
* Mule / Fraud reporting) as pill-style tabs above a router-outlet.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-cfcfrms-shell',
|
||||
templateUrl: './cfcfrms-shell.component.html',
|
||||
styleUrls: ['./cfcfrms-shell.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatTabNav,
|
||||
MatTabLink,
|
||||
RouterLinkActive,
|
||||
MatTabNavPanel,
|
||||
RouterOutlet,
|
||||
FaIconComponent
|
||||
]
|
||||
})
|
||||
export class CfcfrmsShellComponent {}
|
||||
Reference in New Issue
Block a user