181 lines
6.9 KiB
HTML
181 lines
6.9 KiB
HTML
<!--
|
|
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/.
|
|
-->
|
|
|
|
<mat-card class="container">
|
|
<!-- Header Bar -->
|
|
<div class="table-header">
|
|
<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
|
|
mat-stroked-button
|
|
[routerLink]="['../', 'organization', 'bulk-import', 'Clients']"
|
|
*mifosxHasPermission="'CREATE_CLIENT'"
|
|
class="btn-import"
|
|
>
|
|
<fa-icon icon="download"></fa-icon>
|
|
{{ 'labels.buttons.Import Client' | translate }}
|
|
</button>
|
|
<button
|
|
mat-flat-button
|
|
color="primary"
|
|
[routerLink]="['create']"
|
|
*mifosxHasPermission="'CREATE_CLIENT'"
|
|
class="btn-create"
|
|
>
|
|
<fa-icon icon="plus"></fa-icon>
|
|
{{ 'labels.buttons.Create Client' | translate }}
|
|
</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 -->
|
|
<div [hidden]="!existsClientsToFilter" class="table-container">
|
|
@if (isLoading) {
|
|
<mat-progress-bar mode="indeterminate" class="table-loader"></mat-progress-bar>
|
|
}
|
|
|
|
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortChanged($event)" class="modern-table">
|
|
<!-- Name Column -->
|
|
<ng-container matColumnDef="displayName">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
|
<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>
|
|
|
|
<!-- CIF Number Column -->
|
|
<ng-container matColumnDef="cifNumber">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.CIF Number' | translate }}</th>
|
|
<td mat-cell *matCellDef="let row" class="cell-mono">{{ row.cifNumber }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Legal Form Column -->
|
|
<ng-container matColumnDef="legalForm">
|
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Legal Form' | translate }}</th>
|
|
<td mat-cell *matCellDef="let row">
|
|
<span class="legal-form-badge" [ngClass]="row.legalForm?.id === 2 ? 'entity' : 'person'">
|
|
{{ row.legalForm?.id === 2 ? 'Non-Individual' : 'Individual' }}
|
|
</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Status Column -->
|
|
<ng-container matColumnDef="status">
|
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Status' | translate }}</th>
|
|
<td mat-cell *matCellDef="let row">
|
|
<span class="status-badge" [ngClass]="row.status.code | statusLookup">
|
|
{{ row.status.value | translate }}
|
|
</span>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Profile Completion Column -->
|
|
<ng-container matColumnDef="profileCompletion">
|
|
<th mat-header-cell *matHeaderCellDef>Profile</th>
|
|
<td mat-cell *matCellDef="let row">
|
|
<div class="profile-steps">
|
|
@for (step of getProfileSteps(row); track step.label) {
|
|
<span
|
|
class="step-dot"
|
|
[class.done]="step.done"
|
|
[matTooltip]="step.label + (step.done ? ' ✓' : ' — Pending')"
|
|
>
|
|
{{ step.label.charAt(0) }}
|
|
</span>
|
|
}
|
|
</div>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Actions Column -->
|
|
<ng-container matColumnDef="actions">
|
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
|
<td mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
|
|
<div class="action-icons">
|
|
<button mat-button class="action-chip action-chip--view" [routerLink]="[row.id, 'general']">
|
|
<mat-icon>visibility</mat-icon>
|
|
View
|
|
</button>
|
|
<button mat-button class="action-chip action-chip--edit" [routerLink]="[row.id, 'edit']">
|
|
<mat-icon>edit_note</mat-icon>
|
|
Edit
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
|
</table>
|
|
|
|
<mat-paginator
|
|
[pageSize]="pageSize"
|
|
[pageSizeOptions]="[5, 50, 100]"
|
|
[length]="totalRows"
|
|
(page)="pageChanged($event)"
|
|
showFirstLastButtons
|
|
></mat-paginator>
|
|
</div>
|
|
|
|
<!-- Empty State -->
|
|
<div class="empty-state" *ngIf="notExistsClientsToFilter">
|
|
<fa-icon icon="search" class="empty-icon"></fa-icon>
|
|
<p class="empty-text">{{ 'labels.text.No client was found' | translate }}</p>
|
|
</div>
|
|
</mat-card>
|