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
83 lines
3.1 KiB
TypeScript
83 lines
3.1 KiB
TypeScript
import Link from 'next/link';
|
|
import { VerticalFarm } from '../../lib/vertical-farming/types';
|
|
|
|
interface FarmCardProps {
|
|
farm: VerticalFarm;
|
|
}
|
|
|
|
export default function FarmCard({ farm }: FarmCardProps) {
|
|
const statusColors: Record<string, string> = {
|
|
offline: 'bg-gray-100 text-gray-800',
|
|
starting: 'bg-yellow-100 text-yellow-800',
|
|
operational: 'bg-green-100 text-green-800',
|
|
maintenance: 'bg-orange-100 text-orange-800',
|
|
emergency: 'bg-red-100 text-red-800',
|
|
};
|
|
|
|
const activeZones = farm.zones.filter(z => z.status !== 'empty' && z.status !== 'cleaning').length;
|
|
|
|
return (
|
|
<Link href={`/vertical-farm/${farm.id}`}>
|
|
<a className="block bg-white rounded-lg shadow-lg p-6 hover:shadow-xl transition border border-gray-200">
|
|
<div className="flex justify-between items-start mb-4">
|
|
<div>
|
|
<h3 className="text-xl font-bold text-gray-900">{farm.name}</h3>
|
|
<p className="text-sm text-gray-600">
|
|
{farm.location.city}, {farm.location.country}
|
|
</p>
|
|
</div>
|
|
<span
|
|
className={`px-3 py-1 rounded-full text-xs font-semibold ${
|
|
statusColors[farm.status] || 'bg-gray-100 text-gray-800'
|
|
}`}
|
|
>
|
|
{farm.status.replace('_', ' ')}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4 mb-4">
|
|
<div className="bg-gray-50 rounded-lg p-3">
|
|
<p className="text-xs text-gray-600">Active Zones</p>
|
|
<p className="text-2xl font-bold text-green-600">
|
|
{activeZones}/{farm.zones.length}
|
|
</p>
|
|
</div>
|
|
<div className="bg-gray-50 rounded-lg p-3">
|
|
<p className="text-xs text-gray-600">Active Plants</p>
|
|
<p className="text-2xl font-bold text-green-600">
|
|
{farm.specs.currentActivePlants.toLocaleString()}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<div className="flex items-center justify-between text-sm">
|
|
<span className="text-gray-600">Capacity</span>
|
|
<span className="font-medium">{farm.currentCapacityUtilization}%</span>
|
|
</div>
|
|
<div className="w-full bg-gray-200 rounded-full h-2">
|
|
<div
|
|
className="bg-green-600 h-2 rounded-full transition-all"
|
|
style={{ width: `${farm.currentCapacityUtilization}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4 pt-4 border-t border-gray-200 grid grid-cols-3 gap-2 text-center">
|
|
<div>
|
|
<p className="text-xs text-gray-600">Area</p>
|
|
<p className="text-sm font-semibold">{farm.specs.growingAreaSqm}m²</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-xs text-gray-600">Levels</p>
|
|
<p className="text-sm font-semibold">{farm.specs.numberOfLevels}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-xs text-gray-600">Efficiency</p>
|
|
<p className="text-sm font-semibold">{farm.energyEfficiencyScore}%</p>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</Link>
|
|
);
|
|
}
|