feat: complete UI redesign — client creation tabs, footer, home page, CIF & occupation fields
- Client creation: replaced vertical stepper with 3-tab layout (General, KYC & Nominee, Preview) - All form fields redesigned with appearance="outline" and section grouping - Preview tab with profile card, info tables, KYC details, family members - Footer redesigned: security bar, LincShield certifications, regulatory & legal, quick navigation, support & contact, LincPay branding - Home page redesigned: welcome banner, quick action cards, info row - Client view header redesigned: ID chips row (Account No, CIF Number, External Id), 4-column details grid - Added CIF Number column to clients list table - Added CIF Number display to client view sidebar and personal data tab - Added occupationCategoryId and occupationId dropdowns to client creation form - Added occupation fields to client view sidebar, personal data tab, and preview - Added 51+ missing translation keys to en-US.json - Toolbar: added Last login chip - Registered faUserPlus icon Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
b3a4cce0cf
commit
7b1f2e8ad7
@@ -7,50 +7,66 @@
|
||||
-->
|
||||
|
||||
<mat-card class="container">
|
||||
<div class="layout-column layout-gt-sm-row align-gt-sm-start-center">
|
||||
<div class="search-box m-r-30">
|
||||
<mat-form-field class="search-box">
|
||||
<!-- 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 }}"
|
||||
class="search-box"
|
||||
(keydown.enter)="search($event.target.value)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@if (existsClientsToFilter) {
|
||||
<div class="filter-box">
|
||||
<mat-checkbox #showClosedAccounts labelPosition="after" class="m-r-10"
|
||||
>{{ 'labels.inputs.Show Closed Accounts' | translate }}
|
||||
|
||||
@if (existsClientsToFilter) {
|
||||
<mat-checkbox #showClosedAccounts labelPosition="after" class="table-checkbox">
|
||||
{{ 'labels.inputs.Show Closed Accounts' | translate }}
|
||||
</mat-checkbox>
|
||||
}
|
||||
|
||||
<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 class="action-button gap-25px">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
[routerLink]="['../', 'organization', 'bulk-import', 'Clients']"
|
||||
*mifosxHasPermission="'CREATE_CLIENT'"
|
||||
>
|
||||
<fa-icon icon="download" class="m-r-20"></fa-icon>{{ 'labels.buttons.Import Client' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_CLIENT'">
|
||||
<fa-icon icon="plus" class="m-r-20"></fa-icon>{{ 'labels.buttons.Create Client' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div [hidden]="!existsClientsToFilter" class="client-list">
|
||||
<!-- Table -->
|
||||
<div [hidden]="!existsClientsToFilter" class="table-container">
|
||||
@if (isLoading) {
|
||||
<div>
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
||||
<mat-progress-bar mode="indeterminate" class="table-loader"></mat-progress-bar>
|
||||
}
|
||||
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortChanged($event)" class="bordered-table">
|
||||
|
||||
<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" [routerLink]="[row.id, 'general']">
|
||||
<td mat-cell *matCellDef="let row" [routerLink]="[row.id, 'general']" class="cell-link">
|
||||
{{ hideClientData ? maskName(row.displayName) : row.displayName }}
|
||||
</td>
|
||||
</ng-container>
|
||||
@@ -58,15 +74,21 @@
|
||||
<!-- Account no Column -->
|
||||
<ng-container matColumnDef="accountNumber">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Account No' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<td mat-cell *matCellDef="let row" class="cell-mono">
|
||||
<mifosx-account-number display="left" accountNo="{{ row.accountNumber }}"></mifosx-account-number>
|
||||
</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>
|
||||
|
||||
<!-- External ID Column -->
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.External Id' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<td mat-cell *matCellDef="let row" class="cell-mono">
|
||||
<mifosx-external-identifier display="left" externalId="{{ row.externalId }}"></mifosx-external-identifier>
|
||||
</td>
|
||||
</ng-container>
|
||||
@@ -75,22 +97,20 @@
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Status' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<div [ngClass]="row.status.code | statusLookup">
|
||||
<fa-icon icon="stop"></fa-icon>
|
||||
<span class="m-l-10 status">
|
||||
{{ row.status.value | translate }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="status-badge" [ngClass]="row.status.code | statusLookup">
|
||||
{{ row.status.value | translate }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Office Column -->
|
||||
<ng-container matColumnDef="officeName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Office Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row">{{ row.officeName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="select-row"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator
|
||||
@@ -102,10 +122,9 @@
|
||||
></mat-paginator>
|
||||
</div>
|
||||
|
||||
<div class="alert" [hidden]="!notExistsClientsToFilter">
|
||||
<div class="message">
|
||||
<i class="fa fa-exclamation-circle alert-check"></i>
|
||||
{{ 'labels.text.No client was found' | translate }}
|
||||
</div>
|
||||
<!-- Empty State -->
|
||||
<div class="empty-state" [hidden]="!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>
|
||||
|
||||
Reference in New Issue
Block a user