401 lines
16 KiB
HTML
401 lines
16 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/.
|
|
-->
|
|
|
|
<div class="cur-view">
|
|
<!-- ─── Dormancy risk alert (only when subStatus has left Active) ──── -->
|
|
<!-- Shown only when the account's product has Dormancy Alert = Yes -->
|
|
@if (currentAccountData?.dormancyAlert) {
|
|
<mifosx-dormancy-alert-panel [accountData]="currentAccountData"></mifosx-dormancy-alert-panel>
|
|
}
|
|
|
|
<!-- ─── 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="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>
|
|
} @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>
|
|
}
|
|
</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) {
|
|
<mifosx-account-number accountNo="{{ currentAccountData.clientAccountNo }}"></mifosx-account-number>
|
|
}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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>
|
|
}
|
|
|
|
<!-- 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" class="cur-action-menu" xPosition="before">
|
|
<div class="cur-menu" (click)="$event.stopPropagation()">
|
|
<header class="cur-menu__head">
|
|
<fa-icon icon="bolt" class="cur-menu__head-ico"></fa-icon>
|
|
<div>
|
|
<div class="cur-menu__head-title">Account Actions</div>
|
|
<div class="cur-menu__head-sub">Manage deposits, blocks, interest & more</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="cur-menu__body">
|
|
<!-- Transact: singleButtons + options of kind 'transact' -->
|
|
@if (hasKind('transact')) {
|
|
<div class="cur-menu__group">
|
|
<div class="cur-menu__group-title">Transact</div>
|
|
@for (item of buttonConfig.singleButtons; track item.name) {
|
|
@if (kindOf(item.name) === 'transact') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--transact"
|
|
*mifosxHasPermission="item.taskPermissionName"
|
|
(click)="doAction(item.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(item.name, item.icon)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + item.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
@for (option of buttonConfig.options; track option.name) {
|
|
@if (kindOf(option.name) === 'transact') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--transact"
|
|
*mifosxHasPermission="option.taskPermissionName"
|
|
(click)="doAction(option.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(option.name)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + option.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- Restrict: singleButtons + options of kind 'block' -->
|
|
@if (hasKind('block')) {
|
|
<div class="cur-menu__group">
|
|
<div class="cur-menu__group-title">Restrict</div>
|
|
@for (item of buttonConfig.singleButtons; track item.name) {
|
|
@if (kindOf(item.name) === 'block') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--block"
|
|
*mifosxHasPermission="item.taskPermissionName"
|
|
(click)="doAction(item.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(item.name, item.icon)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + item.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
@for (option of buttonConfig.options; track option.name) {
|
|
@if (kindOf(option.name) === 'block') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--block"
|
|
*mifosxHasPermission="option.taskPermissionName"
|
|
(click)="doAction(option.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(option.name)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + option.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- Interest: singleButtons + options of kind 'interest' -->
|
|
@if (hasKind('interest')) {
|
|
<div class="cur-menu__group">
|
|
<div class="cur-menu__group-title">Interest</div>
|
|
@for (item of buttonConfig.singleButtons; track item.name) {
|
|
@if (kindOf(item.name) === 'interest') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--interest"
|
|
*mifosxHasPermission="item.taskPermissionName"
|
|
(click)="doAction(item.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(item.name, item.icon)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + item.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
@for (option of buttonConfig.options; track option.name) {
|
|
@if (kindOf(option.name) === 'interest') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--interest"
|
|
*mifosxHasPermission="option.taskPermissionName"
|
|
(click)="doAction(option.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(option.name)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + option.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- Admin: singleButtons + options of kind 'admin', hidden only when blocked -->
|
|
@if (hasKind('admin') && !currentAccountData.subStatus.block) {
|
|
<div class="cur-menu__group">
|
|
<div class="cur-menu__group-title">Admin</div>
|
|
@for (item of buttonConfig.singleButtons; track item.name) {
|
|
@if (kindOf(item.name) === 'admin') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--admin"
|
|
*mifosxHasPermission="item.taskPermissionName"
|
|
(click)="doAction(item.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(item.name, item.icon)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + item.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
@for (option of buttonConfig.options; track option.name) {
|
|
@if (kindOf(option.name) === 'admin') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--admin"
|
|
*mifosxHasPermission="option.taskPermissionName"
|
|
(click)="doAction(option.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(option.name)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + option.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- Danger zone: singleButtons + options of kind 'danger' -->
|
|
@if (hasKind('danger')) {
|
|
<div class="cur-menu__group cur-menu__group--danger">
|
|
<div class="cur-menu__group-title">Danger zone</div>
|
|
@for (item of buttonConfig.singleButtons; track item.name) {
|
|
@if (kindOf(item.name) === 'danger') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--danger"
|
|
*mifosxHasPermission="item.taskPermissionName"
|
|
(click)="doAction(item.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(item.name, item.icon)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + item.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
@for (option of buttonConfig.options; track option.name) {
|
|
@if (kindOf(option.name) === 'danger') {
|
|
<button
|
|
mat-menu-item
|
|
class="cur-menu__item cur-menu__item--danger"
|
|
*mifosxHasPermission="option.taskPermissionName"
|
|
(click)="doAction(option.name)"
|
|
>
|
|
<span class="cur-menu__ico"><fa-icon [icon]="iconOf(option.name)"></fa-icon></span>
|
|
<span class="cur-menu__label">{{ 'labels.menus.' + option.name | translate }}</span>
|
|
</button>
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</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>
|
|
@if (!isNonIndividualClient) {
|
|
<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>
|
|
</div>
|
|
</mat-tab-nav-panel>
|
|
</div>
|