localgreenchain/components/vertical-farm/ResourceUsageChart.tsx
Claude 2f7f22ca22
Add vertical farming UI components and pages
Components:
- FarmCard: Farm summary display with status and metrics
- ZoneGrid: Multi-level zone layout visualization
- ZoneDetailCard: Individual zone details with environment readings
- EnvironmentGauge: Real-time environmental parameter display
- BatchProgress: Crop batch progress tracking with health scores
- RecipeSelector: Growing recipe browser and selector
- AlertPanel: Environment alerts display and management
- GrowthStageIndicator: Visual growth stage progress tracker
- ResourceUsageChart: Energy/water usage analytics visualization

Pages:
- /vertical-farm: Dashboard with farm listing and stats
- /vertical-farm/register: Multi-step farm registration form
- /vertical-farm/[farmId]: Farm detail view with zones and alerts
- /vertical-farm/[farmId]/zones: Zone management with batch starting
- /vertical-farm/[farmId]/batches: Batch management and harvesting
- /vertical-farm/[farmId]/analytics: Farm analytics and performance metrics
2025-11-22 18:35:57 +00:00

124 lines
5.3 KiB
TypeScript

import { ResourceUsage } from '../../lib/vertical-farming/types';
interface ResourceUsageChartProps {
usage: ResourceUsage;
showBenchmarks?: boolean;
}
export default function ResourceUsageChart({ usage, showBenchmarks = true }: ResourceUsageChartProps) {
const formatCurrency = (value: number) =>
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value);
const efficiencyColor = usage.efficiencyVsBenchmark >= 100
? 'text-green-600'
: usage.efficiencyVsBenchmark >= 80
? 'text-yellow-600'
: 'text-red-600';
return (
<div className="space-y-6">
{/* Summary Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="bg-blue-50 rounded-lg p-4">
<p className="text-sm text-blue-700">Electricity</p>
<p className="text-2xl font-bold text-blue-900">{usage.electricityKwh.toLocaleString()} kWh</p>
<p className="text-sm text-blue-600">{formatCurrency(usage.electricityCostUsd)}</p>
</div>
<div className="bg-cyan-50 rounded-lg p-4">
<p className="text-sm text-cyan-700">Water</p>
<p className="text-2xl font-bold text-cyan-900">{usage.waterUsageL.toLocaleString()} L</p>
<p className="text-sm text-cyan-600">{formatCurrency(usage.waterCostUsd)}</p>
</div>
<div className="bg-green-50 rounded-lg p-4">
<p className="text-sm text-green-700">CO2</p>
<p className="text-2xl font-bold text-green-900">{usage.co2UsedKg.toFixed(1)} kg</p>
<p className="text-sm text-green-600">{formatCurrency(usage.co2CostUsd)}</p>
</div>
<div className="bg-purple-50 rounded-lg p-4">
<p className="text-sm text-purple-700">Nutrients</p>
<p className="text-2xl font-bold text-purple-900">{usage.nutrientsUsedL.toFixed(1)} L</p>
<p className="text-sm text-purple-600">{formatCurrency(usage.nutrientCostUsd)}</p>
</div>
</div>
{/* Efficiency Metrics */}
<div className="bg-white rounded-lg shadow p-6">
<h4 className="font-semibold text-gray-900 mb-4">Efficiency Per kg Produce</h4>
<div className="grid grid-cols-3 gap-4">
<div className="text-center">
<p className="text-3xl font-bold text-blue-600">{usage.kwhPerKgProduce.toFixed(1)}</p>
<p className="text-sm text-gray-600">kWh/kg</p>
{showBenchmarks && (
<p className="text-xs text-gray-500">
Industry: {usage.industryBenchmarkKwhPerKg} kWh/kg
</p>
)}
</div>
<div className="text-center">
<p className="text-3xl font-bold text-cyan-600">{usage.litersPerKgProduce.toFixed(1)}</p>
<p className="text-sm text-gray-600">L/kg</p>
{showBenchmarks && (
<p className="text-xs text-gray-500">
Industry: {usage.industryBenchmarkLitersPerKg} L/kg
</p>
)}
</div>
<div className="text-center">
<p className="text-3xl font-bold text-green-600">{formatCurrency(usage.costPerKgProduce)}</p>
<p className="text-sm text-gray-600">$/kg</p>
</div>
</div>
</div>
{/* Renewable & Recycled */}
<div className="grid grid-cols-2 gap-4">
<div className="bg-white rounded-lg shadow p-4">
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-600">Renewable Energy</span>
<span className="font-semibold text-green-600">{usage.renewablePercent}%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-3">
<div
className="bg-green-500 h-3 rounded-full"
style={{ width: `${usage.renewablePercent}%` }}
/>
</div>
</div>
<div className="bg-white rounded-lg shadow p-4">
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-600">Water Recycled</span>
<span className="font-semibold text-cyan-600">{usage.waterRecycledPercent}%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-3">
<div
className="bg-cyan-500 h-3 rounded-full"
style={{ width: `${usage.waterRecycledPercent}%` }}
/>
</div>
</div>
</div>
{/* Overall Efficiency */}
{showBenchmarks && (
<div className="bg-gray-50 rounded-lg p-4 text-center">
<p className="text-sm text-gray-600 mb-2">Overall Efficiency vs Industry Benchmark</p>
<p className={`text-4xl font-bold ${efficiencyColor}`}>
{usage.efficiencyVsBenchmark.toFixed(0)}%
</p>
<p className="text-sm text-gray-500 mt-1">
{usage.efficiencyVsBenchmark >= 100
? 'Outperforming industry average'
: usage.efficiencyVsBenchmark >= 80
? 'Near industry average'
: 'Below industry average - optimization needed'}
</p>
</div>
)}
{/* Period Info */}
<p className="text-xs text-gray-500 text-center">
Period: {new Date(usage.periodStart).toLocaleDateString()} - {new Date(usage.periodEnd).toLocaleDateString()}
</p>
</div>
);
}