Spaces:
Sleeping
Sleeping
| /** HeatPumpTable β shows available/excluded heat pumps with comparison data. */ | |
| import { useState } from 'react'; | |
| import { useAnalysisStore } from '../../store/analysisStore'; | |
| export default function HeatPumpTable() { | |
| const hpiResult = useAnalysisStore((s) => s.hpiResult); | |
| const [isExcludedOpen, setIsExcludedOpen] = useState(false); | |
| if (!hpiResult) return null; | |
| const available = hpiResult.heat_pumps.filter((hp) => hp.available); | |
| const excluded = hpiResult.excluded_heat_pumps; | |
| if (available.length === 0 && excluded.length === 0) return null; | |
| return ( | |
| <div className="pa-hp-table-wrap"> | |
| {/* ββ Available heat pumps ββ */} | |
| {available.length > 0 && ( | |
| <> | |
| <p className="pa-hp-section-label"> Integrable heat pumps</p> | |
| <table className="pa-table pa-hp-table"> | |
| <thead> | |
| <tr> | |
| <th>Heat Pump</th> | |
| <th>COP</th> | |
| <th>T_source (Β°C)</th> | |
| <th>T_sink (Β°C)</th> | |
| <th>Q_source (kW)</th> | |
| <th>Q_sink (kW)</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {available | |
| .sort((a, b) => (b.cop ?? 0) - (a.cop ?? 0)) | |
| .map((hp) => ( | |
| <tr key={hp.name}> | |
| <td>{hp.name}</td> | |
| <td>{hp.cop?.toFixed(2) ?? 'β'}</td> | |
| <td>{hp.t_source?.toFixed(1) ?? 'β'}</td> | |
| <td>{hp.t_sink?.toFixed(1) ?? 'β'}</td> | |
| <td>{hp.q_source?.toFixed(1) ?? 'β'}</td> | |
| <td>{hp.q_sink?.toFixed(1) ?? 'β'}</td> | |
| </tr> | |
| ))} | |
| </tbody> | |
| </table> | |
| </> | |
| )} | |
| {/* ββ Excluded heat pumps β collapsible, closed by default ββ */} | |
| {excluded.length > 0 && ( | |
| <div className="pa-excluded-hp"> | |
| <p | |
| className="pa-hp-section-label pa-panel-toggle" | |
| onClick={() => setIsExcludedOpen(!isExcludedOpen)} | |
| style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }} | |
| > | |
| <span> Heat pumps that cannot be integrated</span> | |
| <span style={{ transform: isExcludedOpen ? 'rotate(0deg)' : 'rotate(-90deg)', transition: 'transform 0.2s' }}>βΌ</span> | |
| </p> | |
| {isExcludedOpen && ( | |
| <div className="pa-excluded-list"> | |
| {excluded.map((hp) => ( | |
| <div key={hp.name} className="pa-excluded-card"> | |
| <div className="pa-excluded-card-header"> | |
| <span className="pa-excluded-name">{hp.name}</span> | |
| <span className="pa-excluded-badge">Cannot be integrated</span> | |
| </div> | |
| <div className="pa-excluded-reason"> | |
| {hp.reason} | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |