From 7f63dc1df6bf5022546d71b4c3db507299a4beb1 Mon Sep 17 00:00:00 2001 From: RKWojs Date: Fri, 14 Nov 2025 12:08:46 +0100 Subject: [PATCH] feat: add realised vs unrealised value summary to TeamLeadsDashboard with pie chart visualization --- src/app/api/dashboard/route.js | 31 +++++++++++++++- src/app/dashboard/page.js | 66 +++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/app/api/dashboard/route.js b/src/app/api/dashboard/route.js index 603e1e9..b21eef5 100644 --- a/src/app/api/dashboard/route.js +++ b/src/app/api/dashboard/route.js @@ -21,6 +21,20 @@ export async function GET(request) { // Get all projects const projects = getAllProjects(); + // Calculate realised and unrealised values + let realisedValue = 0; + let unrealisedValue = 0; + + projects.forEach(project => { + const value = parseFloat(project.wartosc_zlecenia) || 0; + if (project.project_status === 'fulfilled' && project.completion_date && project.wartosc_zlecenia) { + realisedValue += value; + } else if (project.wartosc_zlecenia && project.project_status !== 'cancelled') { + // Count all non-cancelled projects with values as unrealised + unrealisedValue += value; + } + }); + // Filter completed projects (those with completion_date and fulfilled status) const completedProjects = projects.filter(project => project.completion_date && @@ -30,6 +44,7 @@ export async function GET(request) { // If no data, return sample data for demonstration let chartData; + let summary; if (completedProjects.length === 0) { chartData = [ { month: 'Jan 2024', value: 50000, cumulative: 50000 }, @@ -45,6 +60,10 @@ export async function GET(request) { { month: 'Nov 2024', value: 88000, cumulative: 863000 }, { month: 'Dec 2024', value: 95000, cumulative: 958000 } ]; + summary = { + realisedValue: 958000, + unrealisedValue: 1242000 + }; } else { // Group by month and calculate monthly totals first const monthlyData = {}; @@ -84,9 +103,19 @@ export async function GET(request) { value: Math.round(monthlyData[monthKey].value), cumulative: Math.round(monthlyData[monthKey].cumulative) })); + summary = { + realisedValue: Math.round(realisedValue), + unrealisedValue: Math.round(unrealisedValue) + }; } - return NextResponse.json(chartData); + return NextResponse.json({ + chartData, + summary: { + realisedValue: Math.round(realisedValue), + unrealisedValue: Math.round(unrealisedValue) + } + }); } catch (error) { console.error('Dashboard API error:', error); diff --git a/src/app/dashboard/page.js b/src/app/dashboard/page.js index bc654c2..744f32b 100644 --- a/src/app/dashboard/page.js +++ b/src/app/dashboard/page.js @@ -1,10 +1,11 @@ "use client"; import { useState, useEffect } from "react"; -import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, BarChart, Bar, ComposedChart } from 'recharts'; +import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, BarChart, Bar, ComposedChart, PieChart, Pie, Cell } from 'recharts'; export default function TeamLeadsDashboard() { const [chartData, setChartData] = useState([]); + const [summaryData, setSummaryData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -19,7 +20,8 @@ export default function TeamLeadsDashboard() { throw new Error('Failed to fetch dashboard data'); } const data = await response.json(); - setChartData(data); + setChartData(data.chartData || []); + setSummaryData(data.summary || null); } catch (err) { setError(err.message); } finally { @@ -125,8 +127,64 @@ export default function TeamLeadsDashboard() { )} -
-

This chart shows the cumulative value of completed projects over time, with monthly additions.

+
+

+ Realised vs Unrealised Value +

+ + {summaryData ? ( +
+ + + `${name}: ${(percent * 100).toFixed(0)}%`} + > + + + + formatCurrency(value)} /> + + + +
+ ) : ( +
+
No summary data available
+
+ )} + + {summaryData && ( +
+
+
Realised Value
+
+ {formatCurrency(summaryData.realisedValue)} +
+
+
+
Unrealised Value
+
+ {formatCurrency(summaryData.unrealisedValue)} +
+
+
+ )}