import { useState } from 'react' import { useStorage } from '@/hooks/useStorage' import { ModuleComponent, ModuleComponentType, MonthlyValue, Dimensions, PowerSpecs, ProductionPowerSpecs } from '@/types' import Card from '@/components/base/Card' import Button from '@/components/base/Button' import Input from '@/components/base/Input' import Select from '@/components/base/Select' import Table from '@/components/base/Table' import Badge from '@/components/base/Badge' import { validateRequired, validateNumber } from '@/utils/validators' import './ModuleComponentsConfigurationPage.css' const MONTHS = [ 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december' ] as const const MONTH_LABELS: Record = { january: 'January', february: 'February', march: 'March', april: 'April', may: 'May', june: 'June', july: 'July', august: 'August', september: 'September', october: 'October', november: 'November', december: 'December', } const COMPONENT_TYPES: { value: ModuleComponentType; label: string; isOptional: boolean; defaultDuration: number; durationUnit: 'days' | 'hours' }[] = [ { value: 'firstMethanization', label: '1st Methanization (Required)', isOptional: false, defaultDuration: 21, durationUnit: 'days' }, { value: 'waterEvaporation', label: 'Water Evaporation (Optional)', isOptional: true, defaultDuration: 21, durationUnit: 'days' }, { value: 'bioremediationEcosystem1', label: 'Bioremediation Ecosystem 1 (Optional)', isOptional: true, defaultDuration: 21, durationUnit: 'days' }, { value: 'bioremediationEcosystem2', label: 'Bioremediation Ecosystem 2 (Optional)', isOptional: true, defaultDuration: 21, durationUnit: 'days' }, { value: 'bioremediationEcosystem3', label: 'Bioremediation Ecosystem 3 (Optional)', isOptional: true, defaultDuration: 21, durationUnit: 'days' }, { value: 'secondMethanization', label: '2nd Methanization (Required unless no remediation)', isOptional: false, defaultDuration: 21, durationUnit: 'days' }, { value: 'waterEvaporationComposting', label: 'Water Evaporation & Composting (Optional)', isOptional: true, defaultDuration: 18, durationUnit: 'days' }, { value: 'waterUvcTreatment', label: 'Water UV-C Treatment (Optional)', isOptional: true, defaultDuration: 72, durationUnit: 'hours' }, { value: 'waterStorage', label: 'Water Storage', isOptional: false, defaultDuration: 72, durationUnit: 'hours' }, { value: 'spirulinaWaterStorage', label: 'Spirulina in Water Storage (Optional)', isOptional: true, defaultDuration: 21, durationUnit: 'days' }, { value: 'solarPanels', label: 'Solar Panels (Optional)', isOptional: true, defaultDuration: 0, durationUnit: 'days' }, { value: 'bitcoinMining', label: 'Bitcoin Mining (Optional)', isOptional: true, defaultDuration: 0, durationUnit: 'days' }, ] export default function ModuleComponentsConfigurationPage() { const { data, addEntity, updateEntity, deleteEntity } = useStorage() const [editingId, setEditingId] = useState(null) const [formData, setFormData] = useState>({ name: '', type: 'firstMethanization', isOptional: false, defaultDuration: 21, durationUnit: 'days', }) const [errors, setErrors] = useState>({}) const components = data?.moduleComponents || [] const wastes = data?.wastes || [] const selectedComponentType = COMPONENT_TYPES.find(t => t.value === formData.type) // Initialize form data when component type changes const handleTypeChange = (type: ModuleComponentType) => { const typeConfig = COMPONENT_TYPES.find(t => t.value === type) if (typeConfig) { setFormData({ ...formData, type, isOptional: typeConfig.isOptional, defaultDuration: typeConfig.defaultDuration, durationUnit: typeConfig.durationUnit, }) } } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() const newErrors: Record = {} newErrors.name = validateRequired(formData.name) newErrors.type = validateRequired(formData.type) newErrors.defaultDuration = validateNumber(formData.defaultDuration, 0) setErrors(newErrors) if (Object.values(newErrors).some((error) => error !== undefined)) { return } const component: ModuleComponent = { id: editingId || crypto.randomUUID(), name: formData.name!, type: formData.type!, isOptional: formData.isOptional ?? false, defaultDuration: formData.defaultDuration!, durationUnit: formData.durationUnit || 'days', waterConsumptionPerDay: formData.waterConsumptionPerDay, heatConsumptionPerDay: formData.heatConsumptionPerDay, powerConsumption: formData.powerConsumption, totalWetWasteCapacity: formData.totalWetWasteCapacity, totalDryWasteCapacity: formData.totalDryWasteCapacity, totalCompostCapacity: formData.totalCompostCapacity, totalWaterCapacity: formData.totalWaterCapacity, methaneProduction: formData.methaneProduction, addedBiomassProduction: formData.addedBiomassProduction, waterProduction: formData.waterProduction, heatProduction: formData.heatProduction, immobilizationDuration: formData.immobilizationDuration, wasteTypes: formData.wasteTypes, dimensions: formData.dimensions, groundSurface: formData.groundSurface, heatNeedsPerDay: formData.heatNeedsPerDay, coolingNeedsPerDay: formData.coolingNeedsPerDay, productionPower: formData.productionPower, annualExploitationETP: formData.annualExploitationETP, annualMaintenanceETP: formData.annualMaintenanceETP, annualSupervisionETP: formData.annualSupervisionETP, totalMaterialCost: formData.totalMaterialCost, annualExploitationConsumablesCost: formData.annualExploitationConsumablesCost, annualMaintenanceConsumablesCost: formData.annualMaintenanceConsumablesCost, lifetime: formData.lifetime, createdAt: editingId ? components.find((c) => c.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), updatedAt: new Date().toISOString(), } if (editingId) { updateEntity('moduleComponents', editingId, component) } else { addEntity('moduleComponents', component) } resetForm() } const resetForm = () => { setFormData({ name: '', type: 'firstMethanization', isOptional: false, defaultDuration: 21, durationUnit: 'days', }) setEditingId(null) setErrors({}) } const handleEdit = (component: ModuleComponent) => { setFormData(component) setEditingId(component.id) } const handleDelete = (id: string) => { if (confirm('Are you sure you want to delete this module component?')) { deleteEntity('moduleComponents', id) } } // Helper to create empty monthly value const createEmptyMonthlyValue = (): MonthlyValue => ({ january: 0, february: 0, march: 0, april: 0, may: 0, june: 0, july: 0, august: 0, september: 0, october: 0, november: 0, december: 0, }) // Helper to update monthly value const updateMonthlyValue = ( field: 'waterConsumptionPerDay' | 'heatConsumptionPerDay' | 'heatNeedsPerDay' | 'coolingNeedsPerDay', month: keyof MonthlyValue, value: number ) => { const current = formData[field] || createEmptyMonthlyValue() setFormData({ ...formData, [field]: { ...current, [month]: value, }, }) } const tableColumns = [ { key: 'name', header: 'Name', render: (component: ModuleComponent) => component.name, }, { key: 'type', header: 'Type', render: (component: ModuleComponent) => { const typeConfig = COMPONENT_TYPES.find(t => t.value === component.type) return {typeConfig?.label || component.type} }, }, { key: 'duration', header: 'Duration', render: (component: ModuleComponent) => `${component.defaultDuration} ${component.durationUnit}`, }, { key: 'actions', header: 'Actions', render: (component: ModuleComponent) => (
), }, ] return (

Module Components Configuration

{/* Basic Information */}

Basic Information

setFormData({ ...formData, name: e.target.value })} error={errors.name} placeholder="Enter component name" /> setFormData({ ...formData, defaultDuration: parseFloat(e.target.value) || 0 })} error={errors.defaultDuration} />
{/* Consumption Section */}

Consumption (per day, by month, at fixed temperature 13°C)

Water Consumption (L/day or m³/day)

{MONTHS.map((month) => ( updateMonthlyValue('waterConsumptionPerDay', month, parseFloat(e.target.value) || 0)} /> ))}

Heat Consumption (kJ/day or kWh/day at 13°C)

{MONTHS.map((month) => ( updateMonthlyValue('heatConsumptionPerDay', month, parseFloat(e.target.value) || 0)} /> ))}

Power Consumption

setFormData({ ...formData, powerConsumption: { ...formData.powerConsumption, kwh: parseFloat(e.target.value) || 0, kw: formData.powerConsumption?.kw || 0, }, })} /> setFormData({ ...formData, powerConsumption: { ...formData.powerConsumption, kwh: formData.powerConsumption?.kwh || 0, kw: parseFloat(e.target.value) || 0, }, })} />
{/* Capacities Section */}

Capacities

setFormData({ ...formData, totalWetWasteCapacity: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, totalDryWasteCapacity: parseFloat(e.target.value) || undefined })} />
setFormData({ ...formData, totalCompostCapacity: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, totalWaterCapacity: parseFloat(e.target.value) || undefined })} />
{/* Production Section */}

Production

setFormData({ ...formData, methaneProduction: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, addedBiomassProduction: parseFloat(e.target.value) || undefined })} />
setFormData({ ...formData, waterProduction: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, heatProduction: parseFloat(e.target.value) || undefined })} />
{/* Immobilization & Waste Types */}

Immobilization & Waste Types

setFormData({ ...formData, immobilizationDuration: parseFloat(e.target.value) || undefined })} />

Waste Types (select waste IDs that can be processed)

{wastes.map((waste) => ( ))}
{/* Dimensions Section */}

Dimensions

setFormData({ ...formData, dimensions: { ...formData.dimensions, length: parseFloat(e.target.value) || 0, height: formData.dimensions?.height || 0, width: formData.dimensions?.width || 0, }, })} /> setFormData({ ...formData, dimensions: { ...formData.dimensions, length: formData.dimensions?.length || 0, height: parseFloat(e.target.value) || 0, width: formData.dimensions?.width || 0, }, })} /> setFormData({ ...formData, dimensions: { ...formData.dimensions, length: formData.dimensions?.length || 0, height: formData.dimensions?.height || 0, width: parseFloat(e.target.value) || 0, }, })} />
setFormData({ ...formData, groundSurface: parseFloat(e.target.value) || undefined })} />
{/* Needs Section */}

Needs (per day, by month, at fixed temperature 13°C)

Heat Needs (kJ/day or kWh/day at 13°C)

{MONTHS.map((month) => ( updateMonthlyValue('heatNeedsPerDay', month, parseFloat(e.target.value) || 0)} /> ))}

Cooling Needs (kJ/day or kWh/day at 13°C)

{MONTHS.map((month) => ( updateMonthlyValue('coolingNeedsPerDay', month, parseFloat(e.target.value) || 0)} /> ))}
{/* Production Power Section */}

Production Power

setFormData({ ...formData, productionPower: { ...formData.productionPower, kwh: parseFloat(e.target.value) || 0, kw: formData.productionPower?.kw || 0, }, })} /> setFormData({ ...formData, productionPower: { ...formData.productionPower, kwh: formData.productionPower?.kwh || 0, kw: parseFloat(e.target.value) || 0, }, })} />
{/* ETP Section */}

ETP (Full Time Equivalent - Annual)

setFormData({ ...formData, annualExploitationETP: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, annualMaintenanceETP: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, annualSupervisionETP: parseFloat(e.target.value) || undefined })} />
{/* Costs Section */}

Costs (Annual)

setFormData({ ...formData, totalMaterialCost: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, annualExploitationConsumablesCost: parseFloat(e.target.value) || undefined })} />
setFormData({ ...formData, annualMaintenanceConsumablesCost: parseFloat(e.target.value) || undefined })} /> setFormData({ ...formData, lifetime: parseFloat(e.target.value) || undefined })} />
{editingId && ( )}
) }