83 lines
3.5 KiB
TypeScript
83 lines
3.5 KiB
TypeScript
// components/KPI_Table.tsx
|
|
import React from 'react';
|
|
import { SiteDetails } from '@/types/SiteData'; // Adjust import path as necessary
|
|
|
|
interface KPI_TableProps {
|
|
siteData: SiteDetails | null; // Pass the selected site's data as a prop
|
|
}
|
|
|
|
const KPI_Table: React.FC<KPI_TableProps> = ({ siteData }) => {
|
|
|
|
if (!siteData) {
|
|
return (
|
|
<div>
|
|
<h2 className="text-lg font-bold mb-2">Monthly KPI</h2>
|
|
<p className="text-white/70">Select a site to view KPIs.</p>
|
|
<div className="min-h-[275px] w-full flex items-center justify-center border">
|
|
<p>No data available</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// --- KPI Calculations ---
|
|
const monthlyYield = siteData.generationData.reduce((sum, daily) => sum + daily, 0);
|
|
const monthlyConsumption = siteData.consumptionData.reduce((sum, daily) => sum + daily, 0);
|
|
|
|
// Calculate Grid Draw/Export
|
|
let monthlyGridDraw = 0;
|
|
let monthlySolarExport = 0;
|
|
|
|
// A simplistic model for grid draw/export:
|
|
// If generation > consumption, excess is exported.
|
|
// If consumption > generation, deficit is drawn from grid.
|
|
// Note: This is highly simplified. Real-world calculations involve time-of-use, battery storage, etc.
|
|
const netEnergy = monthlyYield - monthlyConsumption;
|
|
if (netEnergy > 0) {
|
|
monthlySolarExport = netEnergy;
|
|
} else {
|
|
monthlyGridDraw = Math.abs(netEnergy);
|
|
}
|
|
|
|
const selfConsumption = Math.min(monthlyYield, monthlyConsumption);
|
|
const savingsFromSelfConsumption = selfConsumption * siteData.gridImportPrice_RM_per_kWh;
|
|
const revenueFromExport = monthlySolarExport * siteData.solarExportTariff_RM_per_kWh;
|
|
const monthlySaved = savingsFromSelfConsumption + revenueFromExport;
|
|
const efficiency = siteData.theoreticalMaxGeneration_kWh && siteData.theoreticalMaxGeneration_kWh > 0
|
|
? (monthlyYield / siteData.theoreticalMaxGeneration_kWh) * 100
|
|
: 0; // Default to 0 or 'N/A' if theoretical max is not set or zero
|
|
|
|
const data = [
|
|
{ kpi: 'Monthly Yield', value: `${monthlyYield.toFixed(0)} kWh` },
|
|
{ kpi: 'Monthly Consumption', value: `${monthlyConsumption.toFixed(0)} kWh` },
|
|
{ kpi: 'Monthly Grid Draw', value: `${monthlyGridDraw.toFixed(0)} kWh` },
|
|
// { kpi: 'Monthly Solar Export', value: `${monthlySolarExport.toFixed(0)} kWh` }, // Can add this if desired
|
|
{ kpi: 'Efficiency', value: `${efficiency.toFixed(1)}%` },
|
|
{ kpi: 'Monthly Saved', value: `RM ${monthlySaved.toFixed(2)}` },
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<h2 className="text-lg font-bold mb-2">Monthly KPI</h2>
|
|
<table className="min-h-[275px] w-full border-collapse border border-gray-700 text-black bg-white">
|
|
<thead>
|
|
<tr className="bg-gray-800">
|
|
<th className="border border-gray-700 p-3 text-left">KPI</th>
|
|
<th className="border border-gray-700 p-3 text-left">Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{data.map((row) => (
|
|
<tr key={row.kpi} className="">
|
|
<td className="border border-gray-700 p-3">{row.kpi}</td>
|
|
<td className="border border-gray-700 p-3">{row.value}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default KPI_Table;
|