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
+20
-27
@@ -6,23 +6,22 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="container">
|
||||
<div class="mat-elevation-z1 m-b-25" [hidden]="!accountWithTransactions">
|
||||
<div class="layout-row align-end">
|
||||
@if (checkStatus()) {
|
||||
<div class="action-button m-b-20 layout-row gap-20px">
|
||||
<mat-checkbox [formControl]="hideReversedParam" (click)="hideReversed()" class="accruals">
|
||||
{{ 'labels.inputs.Hide Reversed' | translate }}</mat-checkbox
|
||||
>
|
||||
<mat-checkbox [formControl]="hideAccrualsParam" (click)="hideAccruals()" class="accruals">
|
||||
{{ 'labels.inputs.Hide Accruals' | translate }}</mat-checkbox
|
||||
>
|
||||
<button mat-raised-button color="primary" [routerLink]="['export']">
|
||||
{{ 'labels.buttons.Export' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="txn-tab">
|
||||
<div class="txn-tab__card" [hidden]="!accountWithTransactions">
|
||||
@if (checkStatus()) {
|
||||
<div class="txn-tab__toolbar">
|
||||
<mat-checkbox [formControl]="hideReversedParam" (click)="hideReversed()" class="txn-tab__check">
|
||||
{{ 'labels.inputs.Hide Reversed' | translate }}
|
||||
</mat-checkbox>
|
||||
<mat-checkbox [formControl]="hideAccrualsParam" (click)="hideAccruals()" class="txn-tab__check">
|
||||
{{ 'labels.inputs.Hide Accruals' | translate }}
|
||||
</mat-checkbox>
|
||||
<span class="txn-tab__spacer"></span>
|
||||
<button mat-flat-button class="txn-tab__export" [routerLink]="['export']">
|
||||
{{ 'labels.buttons.Export' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
<ng-container matColumnDef="row">
|
||||
@@ -59,13 +58,6 @@
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.External Id' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)">
|
||||
<mifosx-external-identifier externalId="{{ transaction.externalId }}"></mifosx-external-identifier>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="transactionType">
|
||||
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Transaction Type' | translate }}</th>
|
||||
<td
|
||||
@@ -176,10 +168,11 @@
|
||||
<mat-paginator [pageSize]="50" [pageSizeOptions]="[50, 100, 200]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
|
||||
<div class="alert" [hidden]="accountWithTransactions">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
<div class="txn-tab__empty" [hidden]="accountWithTransactions">
|
||||
<fa-icon icon="inbox" class="txn-tab__empty-ico"></fa-icon>
|
||||
<div class="txn-tab__empty-title">
|
||||
{{ 'labels.text.No transaction was found' | translate }}
|
||||
</div>
|
||||
<div class="txn-tab__empty-sub">Posted transactions will appear here.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+138
-22
@@ -6,37 +6,153 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
@use 'assets/styles/helper';
|
||||
$navy: #0d1b2a;
|
||||
$slate: #475569;
|
||||
$muted: #64748b;
|
||||
$border: #e2e8f0;
|
||||
$soft: #f8fafc;
|
||||
$blue: #1e40af;
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
.txn-tab {
|
||||
/* Wrapper hero (savings-account-view) already provides the page padding;
|
||||
this tab sits flush so the table can use the full width. */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1% auto;
|
||||
.txn-tab__card {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 1px 3px rgb(15 23 42 / 4%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ─── Toolbar ─────────────────────────────────────────────────────── */
|
||||
.txn-tab__toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
padding: 12px 18px;
|
||||
background: $soft;
|
||||
border-bottom: 1px solid $border;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.txn-tab__check {
|
||||
font-size: 13px;
|
||||
color: $slate;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.txn-tab__spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.txn-tab__export {
|
||||
height: 36px !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 13px !important;
|
||||
padding: 0 16px !important;
|
||||
background: linear-gradient(135deg, #1e88e5 0%, $blue 100%) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* ─── Table ───────────────────────────────────────────────────────── */
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::ng-deep .txn-tab__card {
|
||||
.mat-mdc-header-row {
|
||||
background: $soft;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
margin-left: auto;
|
||||
.mat-mdc-header-cell {
|
||||
font-size: 11.5px;
|
||||
font-weight: 800;
|
||||
color: $slate;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
.mat-mdc-cell {
|
||||
font-size: 13px;
|
||||
color: $navy;
|
||||
padding: 11px 14px;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.account-action-button {
|
||||
min-width: 26px;
|
||||
padding: 0 0 3px;
|
||||
margin: 0 10%;
|
||||
line-height: 25px;
|
||||
.mat-mdc-row:hover {
|
||||
background: #f8fafc;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.accruals {
|
||||
padding-top: 1%;
|
||||
}
|
||||
}
|
||||
/* Tabular numerics on the money columns (Debit / Credit / Balance) +
|
||||
right-align them. */
|
||||
.mat-column-debit,
|
||||
.mat-column-credit,
|
||||
.mat-column-balance {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.mat-column-actions {
|
||||
text-align: center;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
/* Compact paginator */
|
||||
.mat-mdc-paginator {
|
||||
border-top: 1px solid $border;
|
||||
background: $soft;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
/* Row tint variants — strike-through reversed, dim accrual, blue transfer */
|
||||
.strike td {
|
||||
text-decoration: line-through;
|
||||
color: $muted;
|
||||
}
|
||||
|
||||
.accrual td {
|
||||
color: $muted;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.transfer td {
|
||||
color: #6d28d9;
|
||||
}
|
||||
}
|
||||
|
||||
.select-row:hover {
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
/* ─── Empty state ─────────────────────────────────────────────────── */
|
||||
.txn-tab__empty {
|
||||
background: #fff;
|
||||
border: 1px solid $border;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 1px 3px rgb(15 23 42 / 4%);
|
||||
padding: 56px 24px;
|
||||
text-align: center;
|
||||
color: $muted;
|
||||
}
|
||||
|
||||
.txn-tab__empty-ico {
|
||||
font-size: 34px;
|
||||
color: #cbd5e1;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.txn-tab__empty-title {
|
||||
font-size: 14.5px;
|
||||
font-weight: 700;
|
||||
color: $slate;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.txn-tab__empty-sub {
|
||||
font-size: 12.5px;
|
||||
color: $muted;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { Currency } from 'app/shared/models/general.model';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
import { MatButton, MatIconButton } from '@angular/material/button';
|
||||
import { ExternalIdentifierComponent } from '../../../shared/external-identifier/external-identifier.component';
|
||||
import { MatMenuTrigger, MatMenu, MatMenuItem } from '@angular/material/menu';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
@@ -64,7 +63,6 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
NgClass,
|
||||
ExternalIdentifierComponent,
|
||||
MatIconButton,
|
||||
MatMenuTrigger,
|
||||
MatIcon,
|
||||
@@ -102,7 +100,6 @@ export class TransactionsTabComponent implements OnInit {
|
||||
'row',
|
||||
'id',
|
||||
'date',
|
||||
'externalId',
|
||||
'transactionType',
|
||||
'debit',
|
||||
'credit',
|
||||
|
||||
Reference in New Issue
Block a user