feat: Client & CKYC UI improvements — filters, KYC management, image crop+merge

- Clients list: CKYC icon, CKYC Number column, status/legal form/CKYC filters
- CKYC: SFTP upload logs, date formatting, modal z-index fix, non-dismissible dialogs
- KYC Management: new standalone module with alert dashboard, notification scheduler, audit inventory, account status
- Image cropper: ngx-image-cropper integration for front+back document merge into single PNG
- Sidebar: KYC Management menu entry after CKYC

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-04-16 13:51:11 +05:30
co-authored by Claude Opus 4.6
parent 79e455c4ed
commit d72e969dc3
210 changed files with 14273 additions and 1139 deletions
+59 -22
View File
@@ -9,28 +9,14 @@
<mat-card class="container">
<!-- Header Bar -->
<div class="table-header">
<div class="table-title-group">
<h2 class="table-title">
<div class="t-logomark"><span></span><span></span><span></span><span></span></div>
{{ 'labels.menus.Clients' | translate }}
</h2>
<span class="table-count" *ngIf="totalRows">{{ totalRows }} records</span>
</div>
<div class="table-actions">
<mat-form-field class="table-search" appearance="outline">
<input
matInput
placeholder="{{ 'labels.text.SearchByClient' | translate }}"
(keydown.enter)="search($event.target.value)"
/>
</mat-form-field>
@if (existsClientsToFilter) {
<mat-checkbox #showClosedAccounts labelPosition="after" class="table-checkbox">
{{ 'labels.inputs.Show Closed Accounts' | translate }}
</mat-checkbox>
}
<div class="table-header-row">
<div class="table-title-group">
<h2 class="table-title">
<div class="t-logomark"><span></span><span></span><span></span><span></span></div>
{{ 'labels.menus.Clients' | translate }}
</h2>
<span class="table-count" *ngIf="totalRows">{{ totalRows }} records</span>
</div>
<div class="table-buttons">
<button
@@ -54,6 +40,42 @@
</button>
</div>
</div>
<div class="table-filters">
<mat-form-field class="table-search" appearance="outline">
<input
matInput
placeholder="{{ 'labels.text.SearchByClient' | translate }}"
(keydown.enter)="search($event.target.value)"
/>
</mat-form-field>
<mat-form-field class="table-filter" appearance="outline">
<mat-select [(value)]="statusFilter" (selectionChange)="applyClientFilters()" placeholder="Status">
<mat-option value="">All Status</mat-option>
<mat-option value="active">Active</mat-option>
<mat-option value="pending">Pending</mat-option>
<mat-option value="closed">Closed</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="table-filter" appearance="outline">
<mat-select [(value)]="legalFormFilter" (selectionChange)="applyClientFilters()" placeholder="Legal Form">
<mat-option value="">All Forms</mat-option>
<mat-option value="1">Individual</mat-option>
<mat-option value="2">Non-Individual</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="table-filter" appearance="outline">
<mat-select [(value)]="ckycFilter" (selectionChange)="applyClientFilters()" placeholder="CKYC">
<mat-option value="">All CKYC</mat-option>
<mat-option value="done">CKYC Done</mat-option>
<mat-option value="pending">CKYC Pending</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<!-- Table -->
@@ -69,6 +91,9 @@
<td mat-cell *matCellDef="let row" class="cell-link">
<mat-icon class="row-legal-icon" [ngClass]="row.legalForm?.id === 2 ? 'entity' : 'person'">{{ row.legalForm?.id === 2 ? 'business' : 'person' }}</mat-icon>
{{ hideClientData ? maskName(row.displayName) : row.displayName }}
@if (row._ckycDone) {
<mat-icon class="row-ckyc-icon" matTooltip="CKYC Done">verified</mat-icon>
}
</td>
</ng-container>
@@ -86,6 +111,18 @@
<td mat-cell *matCellDef="let row" class="cell-mono">{{ row.cifNumber }}</td>
</ng-container>
<!-- CKYC Number Column -->
<ng-container matColumnDef="ckycNumber">
<th mat-header-cell *matHeaderCellDef>CKYC Number</th>
<td mat-cell *matCellDef="let row" class="cell-mono">
@if (row._ckycNumber) {
{{ row._ckycNumber }}
} @else {
<span class="ckyc-pending">—</span>
}
</td>
</ng-container>
<!-- Legal Form Column -->
<ng-container matColumnDef="legalForm">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Legal Form' | translate }}</th>