diff --git a/src/app/api/dashboard/route.js b/src/app/api/dashboard/route.js new file mode 100644 index 0000000..603e1e9 --- /dev/null +++ b/src/app/api/dashboard/route.js @@ -0,0 +1,95 @@ +// Force this API route to use Node.js runtime +export const runtime = "nodejs"; + +import { NextResponse } from "next/server"; +import { auth } from "@/lib/auth"; +import { getAllProjects } from "@/lib/queries/projects"; + +export async function GET(request) { + try { + const session = await auth(); + + if (!session?.user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + // Only team leads can access dashboard data + if (session.user.role !== 'team_lead') { + return NextResponse.json({ error: "Forbidden" }, { status: 403 }); + } + + // Get all projects + const projects = getAllProjects(); + + // Filter completed projects (those with completion_date and fulfilled status) + const completedProjects = projects.filter(project => + project.completion_date && + project.wartosc_zlecenia && + project.project_status === 'fulfilled' + ); + + // If no data, return sample data for demonstration + let chartData; + if (completedProjects.length === 0) { + chartData = [ + { month: 'Jan 2024', value: 50000, cumulative: 50000 }, + { month: 'Feb 2024', value: 75000, cumulative: 125000 }, + { month: 'Mar 2024', value: 60000, cumulative: 185000 }, + { month: 'Apr 2024', value: 80000, cumulative: 265000 }, + { month: 'May 2024', value: 95000, cumulative: 360000 }, + { month: 'Jun 2024', value: 70000, cumulative: 430000 }, + { month: 'Jul 2024', value: 85000, cumulative: 515000 }, + { month: 'Aug 2024', value: 90000, cumulative: 605000 }, + { month: 'Sep 2024', value: 78000, cumulative: 683000 }, + { month: 'Oct 2024', value: 92000, cumulative: 775000 }, + { month: 'Nov 2024', value: 88000, cumulative: 863000 }, + { month: 'Dec 2024', value: 95000, cumulative: 958000 } + ]; + } else { + // Group by month and calculate monthly totals first + const monthlyData = {}; + + // Sort projects by completion date + completedProjects.sort((a, b) => new Date(a.completion_date) - new Date(b.completion_date)); + + // First pass: calculate monthly totals + completedProjects.forEach(project => { + const date = new Date(project.completion_date); + const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; + const monthName = date.toLocaleDateString('en-US', { year: 'numeric', month: 'short' }); + + if (!monthlyData[monthKey]) { + monthlyData[monthKey] = { + month: monthName, + value: 0 + }; + } + + const projectValue = parseFloat(project.wartosc_zlecenia) || 0; + monthlyData[monthKey].value += projectValue; + }); + + // Second pass: calculate cumulative values + let cumulativeValue = 0; + const sortedMonths = Object.keys(monthlyData).sort((a, b) => a.localeCompare(b)); + + sortedMonths.forEach(monthKey => { + cumulativeValue += monthlyData[monthKey].value; + monthlyData[monthKey].cumulative = cumulativeValue; + }); + + // Convert to array + chartData = sortedMonths.map(monthKey => ({ + month: monthlyData[monthKey].month, + value: Math.round(monthlyData[monthKey].value), + cumulative: Math.round(monthlyData[monthKey].cumulative) + })); + } + + return NextResponse.json(chartData); + + } catch (error) { + console.error('Dashboard API error:', error); + return NextResponse.json({ error: "Internal server error" }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/dashboard/page.js b/src/app/dashboard/page.js new file mode 100644 index 0000000..4935461 --- /dev/null +++ b/src/app/dashboard/page.js @@ -0,0 +1,134 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; + +export default function TeamLeadsDashboard() { + const [chartData, setChartData] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + fetchDashboardData(); + }, []); + + const fetchDashboardData = async () => { + try { + const response = await fetch('/api/dashboard'); + if (!response.ok) { + throw new Error('Failed to fetch dashboard data'); + } + const data = await response.json(); + setChartData(data); + } catch (err) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + const formatCurrency = (value) => { + return new Intl.NumberFormat('pl-PL', { + style: 'currency', + currency: 'PLN', + minimumFractionDigits: 0, + maximumFractionDigits: 0 + }).format(value); + }; + + const CustomTooltip = ({ active, payload, label }) => { + if (active && payload && payload.length) { + return ( +
{`Month: ${label}`}
++ {`Monthly Value: ${formatCurrency(payload[0].value)}`} +
++ {`Cumulative: ${formatCurrency(payload[1].value)}`} +
+This chart shows the cumulative value of completed projects over time, with monthly additions.
+