Skip to content

Commit 75a489d

Browse files
authored
WEB-634 The dashboard menu should display the full credit traceability. (#3078)
1 parent 1577e9d commit 75a489d

18 files changed

+746
-0
lines changed

src/app/loans/loans-routing.module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { ExportTransactionsComponent } from './loans-view/transactions/export-tr
3737
import { GlimAccountComponent } from './glim-account/glim-account.component';
3838
import { CreateGlimAccountComponent } from './glim-account/create-glim-account/create-glim-account.component';
3939
import { LoanBuyDownFeesTabComponent } from './loans-view/loan-buy-down-fees-tab/loan-buy-down-fees-tab.component';
40+
import { LoanAccountDashboardComponent } from './loans-view/loan-account-dashboard/loan-account-dashboard.component';
4041

4142
/** Custom Resolvers */
4243
import { LoanDetailsResolver } from './common-resolvers/loan-details.resolver';
@@ -112,6 +113,11 @@ const routes: Routes = [
112113
data: { title: 'General', breadcrumb: 'General', routeParamBreadcrumb: false },
113114
resolve: {}
114115
},
116+
{
117+
path: 'dashboard',
118+
component: LoanAccountDashboardComponent,
119+
data: { title: 'Dashboard', breadcrumb: 'Dashboard', routeParamBreadcrumb: false }
120+
},
115121
{
116122
path: 'accountdetail',
117123
component: AccountDetailsComponent,
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<!--
2+
Copyright since 2025 Mifos Initiative
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public
5+
License, v. 2.0. If a copy of the MPL was not distributed with this
6+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
-->
8+
9+
<div class="dashboard-container">
10+
<mat-card class="dashboard-header-card">
11+
<mat-card-header class="header">
12+
<h3>
13+
{{ 'labels.heading.Loan Dashboard' | translate }}
14+
</h3>
15+
</mat-card-header>
16+
</mat-card>
17+
18+
<!-- Metrics Cards -->
19+
<div class="metrics-grid">
20+
<mat-card class="metric-card">
21+
<mat-card-content>
22+
<div class="metric-label">{{ 'labels.inputs.Principal Amount' | translate }}</div>
23+
<div class="metric-value">{{ principalAmount | number: '1.2-2' }}</div>
24+
</mat-card-content>
25+
</mat-card>
26+
27+
<mat-card class="metric-card">
28+
<mat-card-content>
29+
<div class="metric-label">{{ 'labels.inputs.Total Repaid' | translate }}</div>
30+
<div class="metric-value success">{{ totalRepaid | number: '1.2-2' }}</div>
31+
<div class="metric-progress">
32+
<div class="progress-bar" [style.width.%]="progressPercentage"></div>
33+
</div>
34+
</mat-card-content>
35+
</mat-card>
36+
37+
<mat-card class="metric-card">
38+
<mat-card-content>
39+
<div class="metric-label">{{ 'labels.inputs.Outstanding Balance' | translate }}</div>
40+
<div class="metric-value warning">{{ outstandingBalance | number: '1.2-2' }}</div>
41+
</mat-card-content>
42+
</mat-card>
43+
44+
<mat-card class="metric-card">
45+
<mat-card-content>
46+
<div class="metric-label">{{ 'labels.inputs.Interest Charged' | translate }}</div>
47+
<div class="metric-value">{{ interestCharged | number: '1.2-2' }}</div>
48+
</mat-card-content>
49+
</mat-card>
50+
</div>
51+
52+
<!-- Charts Section -->
53+
<div class="charts-grid">
54+
<mat-card class="chart-card">
55+
<mat-card-header>
56+
<mat-card-title>
57+
{{ 'labels.heading.Repayment Progress' | translate }}
58+
</mat-card-title>
59+
</mat-card-header>
60+
<mat-card-content>
61+
<div class="chart-container">
62+
<canvas #statusChart></canvas>
63+
@if (!loanData) {
64+
<div class="no-data-message">{{ 'labels.text.Loading data' | translate }}...</div>
65+
}
66+
</div>
67+
</mat-card-content>
68+
</mat-card>
69+
70+
<mat-card class="chart-card">
71+
<mat-card-header>
72+
<mat-card-title>
73+
{{ 'labels.heading.Payment Schedule' | translate }}
74+
</mat-card-title>
75+
</mat-card-header>
76+
<mat-card-content>
77+
<div class="chart-container">
78+
<canvas #paymentsChart></canvas>
79+
@if (!loanData) {
80+
<div class="no-data-message">{{ 'labels.text.Loading data' | translate }}...</div>
81+
} @else if (!loanData.repaymentSchedule?.periods || loanData.repaymentSchedule.periods.length === 0) {
82+
<div class="no-data-message">
83+
{{ 'labels.text.No repayment schedule available' | translate }}
84+
</div>
85+
}
86+
</div>
87+
</mat-card-content>
88+
</mat-card>
89+
</div>
90+
</div>
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/**
2+
* Copyright since 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
.dashboard-container {
10+
padding: 20px;
11+
background: linear-gradient(135deg, #0d47a1 0%, #1565c0 50%, #1976d2 100%);
12+
}
13+
14+
.dashboard-header-card {
15+
margin-bottom: 24px;
16+
padding: 0;
17+
border: none;
18+
background: rgb(255 255 255 / 10%);
19+
backdrop-filter: blur(10px);
20+
21+
.header {
22+
padding: 16px 24px;
23+
background: transparent;
24+
border-bottom: 1px solid rgb(255 255 255 / 20%);
25+
26+
h3 {
27+
margin: 0;
28+
color: white;
29+
font-size: 22px;
30+
font-weight: 600;
31+
display: flex;
32+
align-items: center;
33+
34+
fa-icon {
35+
color: white;
36+
}
37+
}
38+
}
39+
}
40+
41+
.metrics-grid {
42+
display: flex;
43+
flex-wrap: wrap;
44+
gap: 20px;
45+
margin-bottom: 24px;
46+
}
47+
48+
.metrics-grid .metric-card {
49+
flex: 1 1 250px;
50+
min-width: 250px;
51+
}
52+
53+
.metric-card {
54+
background: rgb(255 255 255 / 95%);
55+
border: none;
56+
border-radius: 16px;
57+
box-shadow: 0 8px 24px rgb(0 0 0 / 15%);
58+
transition: all 0.3s ease;
59+
60+
&:hover {
61+
transform: translateY(-4px);
62+
box-shadow: 0 12px 32px rgb(0 0 0 / 20%);
63+
}
64+
65+
mat-card-content {
66+
padding: 24px;
67+
}
68+
69+
.metric-label {
70+
font-size: 12px;
71+
color: #666;
72+
margin-bottom: 8px;
73+
text-transform: uppercase;
74+
letter-spacing: 1px;
75+
font-weight: 600;
76+
}
77+
78+
.metric-value {
79+
font-size: 32px;
80+
font-weight: 700;
81+
color: #1976d2;
82+
margin-bottom: 12px;
83+
84+
&.success {
85+
color: #4caf50;
86+
}
87+
88+
&.warning {
89+
color: #ff9800;
90+
}
91+
}
92+
93+
.metric-progress {
94+
margin-top: 12px;
95+
height: 8px;
96+
background: linear-gradient(90deg, #e3f2fd 0%, #bbdefb 100%);
97+
border-radius: 4px;
98+
overflow: hidden;
99+
100+
.progress-bar {
101+
height: 100%;
102+
background: linear-gradient(90deg, #4caf50 0%, #66bb6a 100%);
103+
transition: width 0.6s ease;
104+
box-shadow: 0 2px 8px rgb(76 175 80 / 30%);
105+
}
106+
}
107+
}
108+
109+
.charts-grid {
110+
display: flex;
111+
flex-wrap: wrap;
112+
gap: 24px;
113+
}
114+
115+
.charts-grid .chart-card {
116+
flex: 1 1 450px;
117+
min-width: 450px;
118+
}
119+
120+
.chart-card {
121+
background: rgb(255 255 255 / 95%);
122+
border: none;
123+
border-radius: 16px;
124+
box-shadow: 0 8px 24px rgb(0 0 0 / 15%);
125+
overflow: hidden;
126+
127+
mat-card-header {
128+
padding: 20px 24px;
129+
border-bottom: 1px solid #e0e0e0;
130+
background: linear-gradient(135deg, #f5f5f5 0%, #fafafa 100%);
131+
132+
mat-card-title {
133+
font-size: 18px;
134+
font-weight: 600;
135+
color: #1976d2;
136+
display: flex;
137+
align-items: center;
138+
gap: 10px;
139+
margin: 0;
140+
141+
fa-icon {
142+
color: #1976d2;
143+
}
144+
}
145+
}
146+
147+
mat-card-content {
148+
padding: 24px;
149+
background: white;
150+
}
151+
152+
.chart-container {
153+
width: 100%;
154+
height: 350px;
155+
position: relative;
156+
157+
canvas {
158+
max-width: 100%;
159+
height: auto !important;
160+
}
161+
162+
.no-data-message {
163+
position: absolute;
164+
top: 50%;
165+
left: 50%;
166+
transform: translate(-50%, -50%);
167+
color: #999;
168+
font-size: 14px;
169+
text-align: center;
170+
font-weight: 500;
171+
}
172+
}
173+
}
174+
175+
@media (width <= 768px) {
176+
.metrics-grid .metric-card {
177+
flex: 1 1 100%;
178+
min-width: 100%;
179+
}
180+
181+
.charts-grid .chart-card {
182+
flex: 1 1 100%;
183+
min-width: 100%;
184+
}
185+
186+
.dashboard-container {
187+
padding: 12px;
188+
}
189+
}

0 commit comments

Comments
 (0)