-
- Poor
- 300-579
-
-
- Fair
- 580-669
-
-
-
Good
-
670-739
+
+
+
+
+
+ {{ financialSummary.creditScore.score }}
+ Official Score
+
+
vs
+
+ {{ financialSummary.creditScore.systemGeneratedCreditScore }}
+ System Generated
+
-
-
Very Good
-
740-799
+
+
+
+
Your score is in the {{
+ getCreditScoreRange() }} range
-
-
Excellent
-
800-850
+
+
+ Last updated on {{ getCreditScoreLastUpdated() || 'March 14, 2025' }}
-
-
-
-
-
Your score is in the Good range
-
-
-
-
-
Last updated on March 14, 2025
+
+
+
Monthly Financial Health
+
+
+
+
{{ getMonthlyIncome() > 0 ? Math.round((1 - getMonthlyExpenses() /
+ getMonthlyIncome()) * 100) : 0 }}%
+
Savings Rate
+
+
+
+
+
+
Income
+
{{ formatCurrency(getMonthlyIncome()) }}
+
+
+
Expenses
+
{{ formatCurrency(getMonthlyExpenses()) }}
+
+
+
Savings
+
{{ formatCurrency(getMonthlyIncome() - getMonthlyExpenses()) }}
+
+
-
-
-
diff --git a/src/app/components/dashboard/dashboard.component.scss b/src/app/components/dashboard/dashboard.component.scss
index 9a033cf0..48234678 100644
--- a/src/app/components/dashboard/dashboard.component.scss
+++ b/src/app/components/dashboard/dashboard.component.scss
@@ -86,181 +86,359 @@
}
}
- // Credit Score Meter
- /* Credit Score Meter - Refined Design Styles */
-.credit-score-container {
- margin: 15px 0 25px;
- padding: 20px;
- background-color: white;
- border-radius: 10px;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
-
- .credit-score-title {
- color: #1b5e20;
- font-weight: 600;
- margin-bottom: 15px;
- font-size: 1.1rem;
- display: flex;
- align-items: center;
-
- i {
- color: #4caf50;
- margin-right: 8px;
- }
- }
-
- .credit-score-meter-container {
- margin-bottom: 15px;
- }
-
- .credit-score-meter {
- height: 8px;
- position: relative;
- margin: 25px 0 5px;
-
- .credit-score-segments {
- display: flex;
- width: 100%;
- height: 100%;
+ // Credit Score Meter - Enhanced Design
+ .credit-score-container {
+ margin: 15px 0 25px;
+ padding: 20px;
+ background-color: white;
border-radius: 10px;
- overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
- .segment {
- height: 100%;
- flex: 1;
-
- &.poor {
- background-color: #f44336;
- }
+ .credit-score-title {
+ color: #1b5e20;
+ font-weight: 600;
+ margin-bottom: 15px;
+ font-size: 1.1rem;
+ display: flex;
+ align-items: center;
- &.fair {
- background-color: #ff9800;
+ i {
+ color: #4caf50;
+ margin-right: 8px;
}
+ }
+
+ .credit-score-meter-container {
+ margin-bottom: 15px;
+ }
+
+ .credit-score-meter {
+ height: 8px;
+ position: relative;
+ margin: 25px 0 5px;
- &.good {
- background-color: #4caf50;
+ .credit-score-segments {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ overflow: hidden;
+
+ .segment {
+ height: 100%;
+ flex: 1;
+
+ &.poor {
+ background-color: #f44336;
+ }
+
+ &.fair {
+ background-color: #ff9800;
+ }
+
+ &.good {
+ background-color: #4caf50;
+ }
+
+ &.very-good {
+ background-color: #2196f3;
+ }
+
+ &.excellent {
+ background-color: #673ab7;
+ }
+ }
}
- &.very-good {
- background-color: #2196f3;
+ .score-marker {
+ position: absolute;
+ bottom: 100%;
+ transform: translateX(-50%);
+ margin-bottom: 5px;
+ transition: left 0.5s ease;
+
+ .marker-arrow {
+ width: 0;
+ height: 0;
+ border-left: 8px solid transparent;
+ border-right: 8px solid transparent;
+ border-top: 8px solid #1b5e20;
+ margin: 0 auto;
+ }
+
+ .marker-value {
+ background-color: #1b5e20;
+ color: white;
+ font-weight: bold;
+ font-size: 0.9rem;
+ padding: 3px 8px;
+ border-radius: 15px;
+ position: absolute;
+ bottom: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ margin-bottom: 3px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ min-width: 40px;
+ text-align: center;
+ transition: background-color 0.3s ease;
+
+ // Different colors for different score ranges
+ &.poor {
+ background-color: #f44336;
+ }
+
+ &.fair {
+ background-color: #ff9800;
+ }
+
+ &.good {
+ background-color: #4caf50;
+ }
+
+ &.very-good {
+ background-color: #2196f3;
+ }
+
+ &.excellent {
+ background-color: #673ab7;
+ }
+ }
}
+ }
+
+ .credit-score-labels {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 10px;
+ padding: 0 2px;
- &.excellent {
- background-color: #673ab7;
+ .range-label {
+ flex: 1;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ span {
+ font-size: 0.8rem;
+ font-weight: 600;
+ margin-bottom: 2px;
+ }
+
+ small {
+ font-size: 0.65rem;
+ color: #757575;
+ }
+
+ &:nth-child(1) span { color: #f44336; }
+ &:nth-child(2) span { color: #ff9800; }
+ &:nth-child(3) span { color: #4caf50; }
+ &:nth-child(4) span { color: #2196f3; }
+ &:nth-child(5) span { color: #673ab7; }
}
}
- }
-
- .score-marker {
- position: absolute;
- bottom: 100%;
- transform: translateX(-50%);
- margin-bottom: 5px;
- .marker-arrow {
- width: 0;
- height: 0;
- border-left: 8px solid transparent;
- border-right: 8px solid transparent;
- border-top: 8px solid #1b5e20;
- margin: 0 auto;
+ // Score comparison section (System vs. Official)
+ .score-comparison {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(0, 0, 0, 0.03);
+ border-radius: 8px;
+ padding: 10px;
+ margin-bottom: 15px;
+
+ .score-type {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 0 15px;
+
+ .score-value {
+ font-size: 1.2rem;
+ font-weight: 700;
+ }
+
+ .score-label {
+ font-size: 0.7rem;
+ color: #757575;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ }
+
+ &.primary-score .score-value {
+ color: #1b5e20;
+ }
+
+ &.system-score .score-value {
+ color: #1565c0;
+ }
+ }
+
+ .score-divider {
+ color: #757575;
+ font-size: 0.8rem;
+ font-weight: 600;
+ padding: 0 10px;
+ }
}
- .marker-value {
- background-color: #1b5e20;
- color: white;
- font-weight: bold;
- font-size: 0.9rem;
- padding: 3px 8px;
- border-radius: 15px;
- position: absolute;
- bottom: 100%;
- left: 50%;
- transform: translateX(-50%);
- margin-bottom: 3px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
- min-width: 40px;
- text-align: center;
+ .score-details {
+ margin-top: 15px;
+ padding-top: 15px;
+ border-top: 1px solid #e0e0e0;
+
+ .score-status {
+ display: flex;
+ align-items: center;
+ margin-bottom: 12px;
+
+ i {
+ margin-right: 10px;
+ font-size: 1.1rem;
+
+ &.text-poor { color: #f44336; }
+ &.text-fair { color: #ff9800; }
+ &.text-good { color: #4caf50; }
+ &.text-very-good { color: #2196f3; }
+ &.text-excellent { color: #673ab7; }
+ }
+
+ div {
+ font-size: 0.9rem;
+
+ strong {
+ &.text-poor { color: #f44336; }
+ &.text-fair { color: #ff9800; }
+ &.text-good { color: #4caf50; }
+ &.text-very-good { color: #2196f3; }
+ &.text-excellent { color: #673ab7; }
+ }
+ }
+ }
+
+ .score-update {
+ display: flex;
+ align-items: center;
+ font-size: 0.85rem;
+ color: #616161;
+
+ i {
+ margin-right: 10px;
+ color: #2196f3;
+ }
+ }
}
}
- }
-
- .credit-score-labels {
- display: flex;
- justify-content: space-between;
- margin-top: 10px;
- padding: 0 2px;
- .range-label {
- flex: 1;
- text-align: center;
- display: flex;
- flex-direction: column;
- align-items: center;
+ // Financial Health Gauge
+ .financial-health-gauge {
+ margin: 30px 0 0;
+ padding: 20px;
+ background-color: white;
+ border-radius: 10px;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
- span {
- font-size: 0.8rem;
+ .gauge-title {
+ color: #1b5e20;
font-weight: 600;
- margin-bottom: 2px;
- }
-
- small {
- font-size: 0.65rem;
- color: #757575;
+ margin-bottom: 20px;
+ font-size: 1.1rem;
+ text-align: center;
}
- &:nth-child(1) span { color: #f44336; }
- &:nth-child(2) span { color: #ff9800; }
- &:nth-child(3) span { color: #4caf50; }
- &:nth-child(4) span { color: #2196f3; }
- &:nth-child(5) span { color: #673ab7; }
- }
- }
-
- .score-details {
- margin-top: 15px;
- padding-top: 15px;
- border-top: 1px solid #e0e0e0;
-
- .score-status {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
-
- i {
- margin-right: 10px;
- font-size: 1.1rem;
+ .gauge-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
}
- div {
- font-size: 0.9rem;
+ .gauge {
+ position: relative;
+ width: 160px;
+ height: 160px;
+ margin-bottom: 20px;
- strong {
- color: #4caf50;
+ .gauge-value-container {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ text-align: center;
+ z-index: 1;
+
+ .gauge-percentage {
+ font-size: 1.8rem;
+ font-weight: 700;
+ color: #1b5e20;
+ }
+
+ .gauge-label {
+ font-size: 0.75rem;
+ color: #757575;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ }
+ }
+
+ .gauge-svg {
+ transform: rotate(-90deg);
+
+ .gauge-background {
+ fill: none;
+ stroke: #e0e0e0;
+ stroke-width: 12;
+ }
+
+ .gauge-progress {
+ fill: none;
+ stroke: #4caf50;
+ stroke-width: 12;
+ stroke-linecap: round;
+ transition: stroke-dasharray 0.6s ease;
+ }
}
}
- }
-
- .score-percentile {
- padding-left: 25px;
- font-size: 0.85rem;
- color: #616161;
- margin-bottom: 12px;
- }
-
- .score-update {
- display: flex;
- align-items: center;
- font-size: 0.85rem;
- color: #616161;
- i {
- margin-right: 10px;
- color: #2196f3;
+ .gauge-summary {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ background-color: rgba(0, 0, 0, 0.02);
+ border-radius: 8px;
+ padding: 15px;
+
+ .gauge-summary-item {
+ text-align: center;
+ flex: 1;
+
+ .summary-label {
+ font-size: 0.75rem;
+ color: #757575;
+ margin-bottom: 5px;
+ }
+
+ .summary-value {
+ font-weight: 600;
+ font-size: 0.95rem;
+ }
+
+ &.income .summary-value {
+ color: #4caf50;
+ }
+
+ &.expenses .summary-value {
+ color: #f44336;
+ }
+
+ &.savings .summary-value {
+ color: #1565c0;
+ }
+ }
}
}
}
-}}
}
/* Application History Styles */
diff --git a/src/app/components/dashboard/dashboard.component.ts b/src/app/components/dashboard/dashboard.component.ts
index 662706f3..4b31803a 100644
--- a/src/app/components/dashboard/dashboard.component.ts
+++ b/src/app/components/dashboard/dashboard.component.ts
@@ -2,6 +2,7 @@ import { Component, OnInit, AfterViewInit } from '@angular/core';
import { LoanApplicationService } from '../../services/loan-application.service';
import { CustomerService } from '../../services/customer.service';
import { AuthService } from '../../services/auth.service';
+import { FinancialSummaryService, FinancialSummary, CreditScore } from '../../services/financial-summary.service';
import { LoanApplication } from '../../models/loan-application.model';
import { Customer } from '../../models/customer.model';
import { FinancialProfile } from '../../models/financial-profile.model';
@@ -18,23 +19,27 @@ export class DashboardComponent implements OnInit, AfterViewInit {
applicationHistory: any[] = [];
customer: Customer | null = null;
financialProfile: FinancialProfile | null = null;
+ financialSummary: FinancialSummary | null = null;
loading = true;
historyLoading = true;
error = '';
historyError = '';
financialChart: any;
applicationChart: any;
+ Math = Math; // Make Math available in the template
constructor(
private loanService: LoanApplicationService,
private customerService: CustomerService,
private authService: AuthService,
+ private financialSummaryService: FinancialSummaryService,
public router: Router
) { }
ngOnInit(): void {
this.loadDashboardData();
this.loadApplicationHistory();
+ this.loadFinancialSummary();
}
ngAfterViewInit(): void {
@@ -104,6 +109,18 @@ export class DashboardComponent implements OnInit, AfterViewInit {
);
}
+ loadFinancialSummary(): void {
+ this.financialSummaryService.getFinancialSummary().subscribe(
+ data => {
+ this.financialSummary = data;
+ console.log('Financial summary loaded:', data);
+ },
+ error => {
+ console.error('Error loading financial summary', error);
+ }
+ );
+ }
+
initFinancialChart(): void {
if (!this.financialProfile) return;
@@ -244,15 +261,89 @@ export class DashboardComponent implements OnInit, AfterViewInit {
}
getCreditScorePercentage(): number {
- if (!this.financialProfile || !this.financialProfile.creditScore) return 0;
+ if (this.financialSummary && this.financialSummary.creditScore) {
+ // Assuming credit scores range from 300 to 850
+ const minScore = 300;
+ const maxScore = 850;
+ const score = this.financialSummary.creditScore.systemGeneratedCreditScore ||
+ this.financialSummary.creditScore.score;
+
+ // Convert to percentage (0-100%)
+ return ((score - minScore) / (maxScore - minScore)) * 100;
+ } else if (this.financialProfile && this.financialProfile.creditScore) {
+ // Fallback to the old method if financialSummary is not available
+ const minScore = 300;
+ const maxScore = 850;
+ const score = this.financialProfile.creditScore;
+ return ((score - minScore) / (maxScore - minScore)) * 100;
+ }
+ return 0;
+ }
+
+ getCreditScore(): number {
+ if (this.financialSummary && this.financialSummary.creditScore) {
+ return this.financialSummary.creditScore.systemGeneratedCreditScore ||
+ this.financialSummary.creditScore.score;
+ } else if (this.financialProfile && this.financialProfile.creditScore) {
+ return this.financialProfile.creditScore;
+ }
+ return 0;
+ }
+
+ getCreditScoreRange(): string {
+ if (this.financialSummary && this.financialSummary.creditScore) {
+ return this.financialSummary.creditScore.range;
+ }
+
+ const score = this.getCreditScore();
+
+ if (score >= 800) return 'Excellent';
+ if (score >= 740) return 'Very Good';
+ if (score >= 670) return 'Good';
+ if (score >= 580) return 'Fair';
+ return 'Poor';
+ }
+
+ getCreditScoreLastUpdated(): string {
+ if (this.financialSummary && this.financialSummary.creditScore) {
+ return this.formatDate(this.financialSummary.creditScore.lastUpdated);
+ }
+ return '';
+ }
+
+ getMonthlyIncome(): number {
+ if (this.financialSummary) {
+ return this.financialSummary.monthlyIncome;
+ } else if (this.financialProfile) {
+ return this.financialProfile.monthlyIncome;
+ }
+ return 0;
+ }
+
+ getMonthlyExpenses(): number {
+ if (this.financialSummary) {
+ return this.financialSummary.monthlyExpenses;
+ } else if (this.financialProfile) {
+ return this.financialProfile.monthlyExpenses;
+ }
+ return 0;
+ }
+
+ // Determine the exact left position for the credit score marker
+ getCreditScorePosition(): string {
+ const percentage = this.getCreditScorePercentage();
+ return `${percentage}%`;
+ }
- // Assuming credit scores range from 300 to 850
- const minScore = 300;
- const maxScore = 850;
- const score = this.financialProfile.creditScore;
+ // Return the appropriate color class based on the credit score
+ getCreditScoreColorClass(): string {
+ const score = this.getCreditScore();
- // Convert to percentage (0-100%)
- return ((score - minScore) / (maxScore - minScore)) * 100;
+ if (score >= 800) return 'excellent';
+ if (score >= 740) return 'very-good';
+ if (score >= 670) return 'good';
+ if (score >= 580) return 'fair';
+ return 'poor';
}
// Get the current user's name from local storage
diff --git a/src/app/services/financial-summary.service.ts b/src/app/services/financial-summary.service.ts
new file mode 100644
index 00000000..5abb1275
--- /dev/null
+++ b/src/app/services/financial-summary.service.ts
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { environment } from '../../environments/environment';
+
+export interface CreditScore {
+ score: number;
+ systemGeneratedCreditScore: number;
+ lastUpdated: string;
+ range: string;
+}
+
+export interface FinancialSummary {
+ monthlyIncome: number;
+ monthlyExpenses: number;
+ creditScore: CreditScore;
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FinancialSummaryService {
+ private apiUrl = `${environment.apiUrl}/financial-summary`;
+
+ constructor(private http: HttpClient) { }
+
+ getFinancialSummary(): Observable
{
+ return this.http.get(this.apiUrl);
+ }
+}
\ No newline at end of file
From dd1728df2ebe05a616d0eaebf69b4beefb66cbc1 Mon Sep 17 00:00:00 2001
From: sanket kothiya <114993639+sanketkothiya2@users.noreply.github.com>
Date: Sun, 30 Mar 2025 12:08:44 -0400
Subject: [PATCH 02/14] check 6
---
.../dashboard/dashboard.component.html | 54 +++--
.../dashboard/dashboard.component.scss | 210 ++++++++++++------
2 files changed, 177 insertions(+), 87 deletions(-)
diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html
index 3b641616..9293e00d 100644
--- a/src/app/components/dashboard/dashboard.component.html
+++ b/src/app/components/dashboard/dashboard.component.html
@@ -25,15 +25,37 @@