feat: Nexora UI upgrade for Current Account, FD, and RD account views
- Current Account: hero header with navy gradient, pill tabs, Nexora card layout for general tab, txn-tab/chg-tab table styles, bank statement passbook - Fixed Deposits: fd-* prefixed hero header, KPI tiles, pill tab nav, nx-card general tab layout, txn-tab transactions, chg-tab charges - Recurring Deposits: rd-* prefixed hero header with three KPI tiles, pill tab nav, nx-card general tab layout, txn-tab transactions, chg-tab charges - Fix: removed broken FA4-format icon references from action menu buttons Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ad6f629c3f
commit
b7d009b22a
+216
-223
@@ -6,239 +6,232 @@
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<mat-card class="account-card">
|
||||
<mat-card-header class="header layout-column">
|
||||
<mat-card-title-group class="header-title-group">
|
||||
<div class="profile-image-container">
|
||||
<div>
|
||||
<img
|
||||
mat-card-md-image
|
||||
class="profile-image"
|
||||
matTooltip="{{ 'tooltips.Current Account' | translate }}"
|
||||
[src]="'assets/images/current_account_placeholder.png'"
|
||||
/>
|
||||
</div>
|
||||
<div class="cur-view">
|
||||
<!-- ─── Gradient hero header ─────────────────────────────────────── -->
|
||||
<header class="cur-hero">
|
||||
<div class="cur-hero__left">
|
||||
<div class="cur-hero__avatar">
|
||||
<fa-icon icon="university"></fa-icon>
|
||||
</div>
|
||||
|
||||
<div class="mat-typography account-card-title">
|
||||
<mat-card-title class="layout-row layout-lt-md-column">
|
||||
<div class="flex-60">
|
||||
<h3>
|
||||
@if (!currentAccountData.subStatus.block) {
|
||||
<i
|
||||
class="fa fa-stop"
|
||||
[ngClass]="currentAccountData.status.code | statusLookup"
|
||||
[matTooltip]="currentAccountData.status.value"
|
||||
></i>
|
||||
}
|
||||
@if (currentAccountData.subStatus.block) {
|
||||
<i
|
||||
class="fa fa-stop"
|
||||
[ngClass]="currentAccountData.subStatus.value | statusLookup"
|
||||
[matTooltip]="currentAccountData.subStatus.value"
|
||||
></i>
|
||||
}
|
||||
</h3>
|
||||
<!-- Product Name Row -->
|
||||
<span class="product-row">
|
||||
<span class="m-r-5">{{ 'labels.inputs.Current Account Product' | translate }} :</span>
|
||||
<span class="m-r-5">
|
||||
<mifosx-long-text textValue="{{ currentAccountData.currentAccountProductName }}"></mifosx-long-text>
|
||||
</span>
|
||||
<div class="cur-hero__info">
|
||||
<!-- Status pill -->
|
||||
<div class="cur-hero__status-row">
|
||||
@if (!currentAccountData.subStatus.block) {
|
||||
<span
|
||||
class="cur-status-pill"
|
||||
[ngClass]="currentAccountData.status.code | statusLookup"
|
||||
[matTooltip]="currentAccountData.status.value"
|
||||
>
|
||||
<span class="cur-status-pill__dot"></span>
|
||||
{{ currentAccountData.status.value }}
|
||||
</span>
|
||||
<!-- Account Number Row -->
|
||||
<span class="account-number-row">
|
||||
<span class="m-r-5">{{ 'labels.inputs.Account Number' | translate }} :</span>
|
||||
<span class="m-r-5">
|
||||
<mifosx-account-number
|
||||
accountNo="{{ currentAccountData.accountNo }}"
|
||||
display="left"
|
||||
></mifosx-account-number>
|
||||
</span>
|
||||
} @else {
|
||||
<span
|
||||
class="cur-status-pill cur-status-pill--warn"
|
||||
[ngClass]="currentAccountData.subStatus.value | statusLookup"
|
||||
[matTooltip]="currentAccountData.subStatus.value"
|
||||
>
|
||||
<span class="cur-status-pill__dot"></span>
|
||||
{{ currentAccountData.subStatus.value }}
|
||||
</span>
|
||||
<!-- External ID Row -->
|
||||
@if (currentAccountData.externalId) {
|
||||
<span class="external-id-row">
|
||||
<span class="m-r-5">{{ 'labels.inputs.External Id' | translate }} :</span>
|
||||
<span>{{ currentAccountData.externalId }}</span>
|
||||
</span>
|
||||
}
|
||||
<span class="account-overview">
|
||||
{{ 'labels.text.' + entityType | translate }} {{ 'labels.inputs.name' | translate }}:
|
||||
}
|
||||
</div>
|
||||
|
||||
<h2 class="cur-hero__title">
|
||||
<mifosx-long-text textValue="{{ currentAccountData.currentAccountProductName }}"></mifosx-long-text>
|
||||
</h2>
|
||||
|
||||
<div class="cur-hero__meta">
|
||||
<span class="cur-hero__meta-item">
|
||||
<span class="cur-hero__meta-label">{{ 'labels.inputs.Account Number' | translate }}</span>
|
||||
<mifosx-account-number
|
||||
accountNo="{{ currentAccountData.accountNo }}"
|
||||
display="left"
|
||||
></mifosx-account-number>
|
||||
</span>
|
||||
|
||||
<span class="cur-hero__meta-item">
|
||||
<span class="cur-hero__meta-label">
|
||||
{{ 'labels.text.' + entityType | translate }} {{ 'labels.inputs.name' | translate }}
|
||||
</span>
|
||||
<span class="cur-hero__meta-value">
|
||||
{{ currentAccountData.clientName || currentAccountData.groupName }}
|
||||
@if (currentAccountData.clientAccountNo) {
|
||||
<span class="m-l-10">
|
||||
<mifosx-account-number accountNo="{{ currentAccountData.clientAccountNo }}"></mifosx-account-number>
|
||||
</span>
|
||||
<mifosx-account-number accountNo="{{ currentAccountData.clientAccountNo }}"></mifosx-account-number>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@if (!currentAccountData.status.rejected && !currentAccountData.status.submittedAndPendingApproval) {
|
||||
<div class="flex-30">
|
||||
<h3>{{ 'labels.heading.Account Overview' | translate }}</h3>
|
||||
<table class="account-overview">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Current Balance' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.accountBalance | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Available Balance' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.availableBalance
|
||||
| currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-5">
|
||||
<button
|
||||
mat-icon-button
|
||||
[matMenuTriggerFor]="accountMenu"
|
||||
aria-label="Loan account actions"
|
||||
yPosition="below"
|
||||
>
|
||||
<mat-icon matListIcon class="actions-menu">
|
||||
<fa-icon icon="bars" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-title>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-menu #accountMenu="matMenu">
|
||||
@for (item of buttonConfig.singleButtons; track item) {
|
||||
<button mat-menu-item *mifosxHasPermission="item.taskPermissionName" (click)="doAction(item.name)">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="{{ item.icon }}" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<span> {{ 'labels.menus.' + item.name | translate }} </span>
|
||||
</button>
|
||||
}
|
||||
|
||||
@if (buttonConfig.options && !currentAccountData.subStatus.block) {
|
||||
<button mat-menu-item [matMenuTriggerFor]="More">{{ 'labels.menus.More' | translate }}</button>
|
||||
<mat-menu #More="matMenu">
|
||||
@for (option of buttonConfig.options; track option) {
|
||||
<span>
|
||||
<button mat-menu-item *mifosxHasPermission="option.taskPermissionName" (click)="doAction(option.name)">
|
||||
{{ 'labels.menus.' + option.name | translate }}
|
||||
</button>
|
||||
</span>
|
||||
}
|
||||
</mat-menu>
|
||||
}
|
||||
</mat-menu>
|
||||
</mat-card-title-group>
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content class="content">
|
||||
@if (isActive) {
|
||||
<nav mat-tab-nav-bar class="navigation-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./general']"
|
||||
routerLinkActive
|
||||
#general="routerLinkActive"
|
||||
[active]="general.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.General' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./transactions']"
|
||||
routerLinkActive
|
||||
#transactions="routerLinkActive"
|
||||
[active]="transactions.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Transactions' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./passbook']"
|
||||
routerLinkActive
|
||||
#passbook="routerLinkActive"
|
||||
[active]="passbook.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Passbook' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./charges']"
|
||||
routerLinkActive
|
||||
#charges="routerLinkActive"
|
||||
[active]="charges.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Charges' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./documents']"
|
||||
routerLinkActive
|
||||
#currentAccountDocuments="routerLinkActive"
|
||||
[active]="currentAccountDocuments.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Documents' | translate }}
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
*mifosxHasPermission="'READ_CURRENTACCOUNTNOTE'"
|
||||
[routerLink]="['./notes']"
|
||||
routerLinkActive
|
||||
#notes="routerLinkActive"
|
||||
[active]="notes.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Notes' | translate }}
|
||||
</a>
|
||||
<ng-container *mifosxHasPermission="'READ_CURRENTACCOUNTCHARGE'">
|
||||
@if (currentAccountData.clientId) {
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./standing-instructions']"
|
||||
routerLinkActive
|
||||
#standingInstructions="routerLinkActive"
|
||||
[active]="standingInstructions.isActive"
|
||||
>
|
||||
{{ 'labels.inputs.Standing Instructions' | translate }}
|
||||
</a>
|
||||
}
|
||||
</ng-container>
|
||||
<a
|
||||
mat-tab-link
|
||||
[routerLink]="['./nominees']"
|
||||
routerLinkActive
|
||||
#nominees="routerLinkActive"
|
||||
[active]="nominees.isActive"
|
||||
>
|
||||
Nominees
|
||||
</a>
|
||||
@for (currentAccountDatatable of currentAccountDatatables; track currentAccountDatatable) {
|
||||
<a
|
||||
mat-tab-link
|
||||
*mifosxHasPermission="'READ_' + currentAccountDatatable.registeredTableName"
|
||||
[routerLink]="['./datatables', currentAccountDatatable.registeredTableName]"
|
||||
routerLinkActive
|
||||
#datatable="routerLinkActive"
|
||||
[active]="datatable.isActive"
|
||||
>
|
||||
{{ currentAccountDatatable.registeredTableName }}
|
||||
</a>
|
||||
}
|
||||
</nav>
|
||||
<!-- Balance KPI strip -->
|
||||
@if (!currentAccountData.status.rejected && !currentAccountData.status.submittedAndPendingApproval) {
|
||||
<div class="cur-hero__kpis">
|
||||
<div class="cur-kpi">
|
||||
<span class="cur-kpi__label">{{ 'labels.inputs.Current Balance' | translate }}</span>
|
||||
<span class="cur-kpi__value">
|
||||
{{ currentAccountData.summary.accountBalance | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="cur-kpi cur-kpi--available">
|
||||
<span class="cur-kpi__label">{{ 'labels.inputs.Available Balance' | translate }}</span>
|
||||
<span class="cur-kpi__value">
|
||||
{{ currentAccountData.summary.availableBalance | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<mat-tab-nav-panel #tabPanel>
|
||||
<!-- Action menu (kebab) -->
|
||||
<div class="cur-hero__actions">
|
||||
<button mat-icon-button [matMenuTriggerFor]="accountMenu" aria-label="Account actions" yPosition="below">
|
||||
<fa-icon icon="ellipsis-v"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-menu #accountMenu="matMenu">
|
||||
@for (item of buttonConfig.singleButtons; track item) {
|
||||
<button mat-menu-item *mifosxHasPermission="item.taskPermissionName" (click)="doAction(item.name)">
|
||||
<mat-icon matListIcon>
|
||||
<fa-icon icon="{{ item.icon }}" size="sm"></fa-icon>
|
||||
</mat-icon>
|
||||
<span> {{ 'labels.menus.' + item.name | translate }} </span>
|
||||
</button>
|
||||
}
|
||||
|
||||
@if (buttonConfig.options && !currentAccountData.subStatus.block) {
|
||||
<button mat-menu-item [matMenuTriggerFor]="More">{{ 'labels.menus.More' | translate }}</button>
|
||||
<mat-menu #More="matMenu">
|
||||
@for (option of buttonConfig.options; track option) {
|
||||
<span>
|
||||
<button mat-menu-item *mifosxHasPermission="option.taskPermissionName" (click)="doAction(option.name)">
|
||||
{{ 'labels.menus.' + option.name | translate }}
|
||||
</button>
|
||||
</span>
|
||||
}
|
||||
</mat-menu>
|
||||
}
|
||||
</mat-menu>
|
||||
</header>
|
||||
|
||||
<!-- ─── Pill-style tab navigation ─────────────────────────────────── -->
|
||||
@if (isActive) {
|
||||
<nav mat-tab-nav-bar class="cur-tabs" [tabPanel]="tabPanel">
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./general']"
|
||||
routerLinkActive
|
||||
#general="routerLinkActive"
|
||||
[active]="general.isActive"
|
||||
>
|
||||
<fa-icon icon="info-circle" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.General' | translate }}</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./transactions']"
|
||||
routerLinkActive
|
||||
#transactions="routerLinkActive"
|
||||
[active]="transactions.isActive"
|
||||
>
|
||||
<fa-icon icon="exchange-alt" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Transactions' | translate }}</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./passbook']"
|
||||
routerLinkActive
|
||||
#passbook="routerLinkActive"
|
||||
[active]="passbook.isActive"
|
||||
>
|
||||
<fa-icon icon="book" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Passbook' | translate }}</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./charges']"
|
||||
routerLinkActive
|
||||
#charges="routerLinkActive"
|
||||
[active]="charges.isActive"
|
||||
>
|
||||
<fa-icon icon="receipt" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Charges' | translate }}</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./documents']"
|
||||
routerLinkActive
|
||||
#currentAccountDocuments="routerLinkActive"
|
||||
[active]="currentAccountDocuments.isActive"
|
||||
>
|
||||
<fa-icon icon="folder-open" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Documents' | translate }}</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
*mifosxHasPermission="'READ_CURRENTACCOUNTNOTE'"
|
||||
[routerLink]="['./notes']"
|
||||
routerLinkActive
|
||||
#notes="routerLinkActive"
|
||||
[active]="notes.isActive"
|
||||
>
|
||||
<fa-icon icon="sticky-note" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Notes' | translate }}</span>
|
||||
</a>
|
||||
<ng-container *mifosxHasPermission="'READ_CURRENTACCOUNTCHARGE'">
|
||||
@if (currentAccountData.clientId) {
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./standing-instructions']"
|
||||
routerLinkActive
|
||||
#standingInstructions="routerLinkActive"
|
||||
[active]="standingInstructions.isActive"
|
||||
>
|
||||
<fa-icon icon="calendar-check" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ 'labels.inputs.Standing Instructions' | translate }}</span>
|
||||
</a>
|
||||
}
|
||||
</ng-container>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
[routerLink]="['./nominees']"
|
||||
routerLinkActive
|
||||
#nominees="routerLinkActive"
|
||||
[active]="nominees.isActive"
|
||||
>
|
||||
<fa-icon icon="user-shield" class="cur-tab__ic"></fa-icon>
|
||||
<span>Nominees</span>
|
||||
</a>
|
||||
@for (currentAccountDatatable of currentAccountDatatables; track currentAccountDatatable) {
|
||||
<a
|
||||
mat-tab-link
|
||||
class="cur-tab"
|
||||
*mifosxHasPermission="'READ_' + currentAccountDatatable.registeredTableName"
|
||||
[routerLink]="['./datatables', currentAccountDatatable.registeredTableName]"
|
||||
routerLinkActive
|
||||
#datatable="routerLinkActive"
|
||||
[active]="datatable.isActive"
|
||||
>
|
||||
<fa-icon icon="table" class="cur-tab__ic"></fa-icon>
|
||||
<span>{{ currentAccountDatatable.registeredTableName }}</span>
|
||||
</a>
|
||||
}
|
||||
</nav>
|
||||
}
|
||||
|
||||
<mat-tab-nav-panel #tabPanel>
|
||||
<div class="cur-body">
|
||||
<router-outlet></router-outlet>
|
||||
</mat-tab-nav-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-tab-nav-panel>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user