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
+44
-35
@@ -7,40 +7,45 @@
|
||||
-->
|
||||
|
||||
<div class="cv-tab-content">
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'labels.text.Search by user' | translate }}"
|
||||
(keyup)="applyFilter($event.target.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="toggleAdvancedSearch()"
|
||||
class="cv-toggle-btn"
|
||||
[attr.aria-label]="
|
||||
showAdvancedSearch
|
||||
? ('labels.buttons.Hide advanced search' | translate)
|
||||
: ('labels.buttons.Show advanced search' | translate)
|
||||
"
|
||||
[attr.aria-expanded]="showAdvancedSearch"
|
||||
>
|
||||
<mat-icon>{{ showAdvancedSearch ? 'arrow_drop_up' : 'arrow_drop_down' }}</mat-icon>
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button mat-stroked-button class="cv-btn cv-btn-approve" (click)="approveChecker()">
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-delete" (click)="deleteChecker()">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-reject" (click)="rejectChecker()">
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
<!-- Action bar (search + advanced toggle + Approve/Delete/Reject) — only
|
||||
rendered when there's actual data to work with. An empty inbox shows
|
||||
the friendly empty-state block below without these controls. -->
|
||||
@if (checkerData) {
|
||||
<div class="cv-action-bar">
|
||||
<mat-form-field appearance="outline" class="cv-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'labels.text.Search by user' | translate }}"
|
||||
(keyup)="applyFilter($event.target.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="toggleAdvancedSearch()"
|
||||
class="cv-toggle-btn"
|
||||
[attr.aria-label]="
|
||||
showAdvancedSearch
|
||||
? ('labels.buttons.Hide advanced search' | translate)
|
||||
: ('labels.buttons.Show advanced search' | translate)
|
||||
"
|
||||
[attr.aria-expanded]="showAdvancedSearch"
|
||||
>
|
||||
<mat-icon>{{ showAdvancedSearch ? 'arrow_drop_up' : 'arrow_drop_down' }}</mat-icon>
|
||||
</button>
|
||||
<div class="cv-action-buttons">
|
||||
<button mat-stroked-button class="cv-btn cv-btn-approve" (click)="approveChecker()">
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>{{ 'labels.buttons.Approve' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-delete" (click)="deleteChecker()">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>{{ 'labels.buttons.Delete' | translate }}
|
||||
</button>
|
||||
<button mat-stroked-button class="cv-btn cv-btn-reject" (click)="rejectChecker()">
|
||||
<fa-icon icon="times" class="m-r-10"></fa-icon>{{ 'labels.buttons.Reject' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (showAdvancedSearch) {
|
||||
<form [formGroup]="makerCheckerSearchForm">
|
||||
@@ -161,16 +166,20 @@
|
||||
}
|
||||
|
||||
@if (checkerData && noSearchedData) {
|
||||
<div class="empty-state">
|
||||
<div class="empty-state empty-state--filter">
|
||||
<i class="fas fa-inbox empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No checker inbox data available for this search' | translate }}</p>
|
||||
<p class="empty-title">No matches</p>
|
||||
<p class="empty-text">No checker inbox items match the current search. Try clearing the filters.</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!checkerData) {
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox empty-icon"></i>
|
||||
<p class="empty-text">{{ 'labels.text.No checker inbox data available for this account' | translate }}</p>
|
||||
<p class="empty-title">Inbox is empty</p>
|
||||
<p class="empty-text">
|
||||
Currently no items in the Checker Inbox. New maker actions awaiting review will appear here.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -210,3 +210,44 @@ $text-muted: #64748b;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Empty state — shown when the inbox has no items at all (search/action bar
|
||||
is hidden in that case) or when the current search has no matches. */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 24px;
|
||||
background: #fff;
|
||||
border: 1px dashed #e2e8f0;
|
||||
border-radius: 14px;
|
||||
text-align: center;
|
||||
margin: 16px 0;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 42px;
|
||||
color: #cbd5e1;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.empty-title {
|
||||
margin: 0 0 4px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #0d1b2a;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin: 0;
|
||||
font-size: 12.5px;
|
||||
color: #64748b;
|
||||
max-width: 380px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
&--filter {
|
||||
background: #f8fafc;
|
||||
border-style: solid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user