Files
KAFM-Project/components/dashboard/iotapplication/hvacPlant.tsx

355 lines
17 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import { BarChart2, Zap, Snowflake, Activity, Target } from "lucide-react";
import Button from "@/components/common/button";
import { Card } from '@/components/common/cardWrapper';
import BarChart from "@/components/charts/barchart"; // Replace path with your actual BarChart component import path
const plantLoadData = [
{ month: '08', height: 'h-[35%]' },
{ month: '09', height: 'h-[38%]' },
{ month: '10', height: 'h-[32%]' },
{ month: '11', height: 'h-[40%]' },
{ month: '12', height: 'h-[52%]' },
{ month: '13', height: 'h-[68%]' },
{ month: '14', height: 'h-[78%]' },
{ month: '15', height: 'h-[78%]' },
{ month: '16', height: 'h-[78%]' },
{ month: '17', height: 'h-[78%]' },
{ month: '18', height: 'h-[78%]' },
{ month: '19', height: 'h-[78%]' }
];
export default function HVACPlantPortal() {
return (
<div className="my-15 text-slate-100 font-sans">
{/* --- HEADER SECTION --- */}
<div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
<div>
<div className="flex items-center gap-2 text-[11px] font-semibold tracking-widest text-[#4e6178] uppercase font-mono">
<span className="text-emerald-400 font-bold">APPLE ONE HQ TOWER</span>
<span></span>
<span>IOT</span>
<span></span>
<span>HVAC PLANT</span>
</div>
<h1 className="text-3xl font-bold text-white tracking-tight mt-1">
Chiller plant & air side
</h1>
<p className="text-sm text-[#7f93ac] mt-2 max-w-xl leading-relaxed">
Live chiller, AHU and plant telemetry with start/stop control commands are audit-logged.
</p>
</div>
{/* --- HEADER BUTTONS --- */}
<div className="flex items-center gap-3 self-start md:mt-2">
<Button className="bg-[#0e1c2e] hover:bg-slate-800 text-slate-200 border border-[#162942] text-xs px-4 py-2 rounded-lg flex items-center gap-2 font-semibold transition-colors">
<BarChart2 className="w-4 h-4 text-slate-400" />
<span>Plant report</span>
</Button>
<Button className="bg-[#10b981] hover:bg-emerald-400 text-slate-950 font-bold text-xs px-4 py-2 rounded-lg flex items-center gap-2 transition-colors shadow-lg">
<Activity className="w-4 h-4 text-slate-950" />
<span>Optimise staging</span>
</Button>
</div>
</div>
{/* --- STAT CARDS (WITH ICON BADGES) --- */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
{/* Card 1: Chillers running */}
<Card className="p-4 min-h-[120px]">
<div className="flex justify-between items-start">
<div className="p-2.5 rounded-lg bg-blue-950/60 border border-blue-800/40 text-blue-400">
<Snowflake className="w-5 h-5" />
</div>
<span className="text-[10px] font-bold text-[#5c738e] tracking-wider uppercase font-mono">
staged
</span>
</div>
<div className="mt-3">
<div className="text-3xl font-extrabold text-white">2 / 3</div>
<p className="text-xs text-[#5c738e] mt-1">Chillers running</p>
</div>
</Card>
{/* Card 2: Avg COP */}
<Card className="p-4 min-h-[120px]">
<div className="flex justify-between items-start">
<div className="p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800/40 text-emerald-400">
<Activity className="w-5 h-5" />
</div>
<span className="text-[10px] font-bold text-emerald-400 tracking-wider uppercase font-mono">
plant efficiency
</span>
</div>
<div className="mt-3">
<div className="text-3xl font-extrabold text-white">5.60</div>
<p className="text-xs text-[#5c738e] mt-1">Avg COP</p>
</div>
</Card>
{/* Card 3: Plant load */}
<Card className="p-4 min-h-[120px]">
<div className="flex justify-between items-start">
<div className="p-2.5 rounded-lg bg-amber-950/50 border border-amber-800/40 text-amber-400">
<Zap className="w-5 h-5" />
</div>
<span className="text-[10px] font-bold text-[#5c738e] tracking-wider uppercase font-mono">
now
</span>
</div>
<div className="mt-3">
<div className="text-3xl font-extrabold text-white">401 kW</div>
<p className="text-xs text-[#5c738e] mt-1">Plant load</p>
</div>
</Card>
{/* Card 4: AHUs running */}
<Card className="p-4 min-h-[120px]">
<div className="flex justify-between items-start">
<div className="p-2.5 rounded-lg bg-teal-950/60 border border-teal-800/40 text-teal-400">
<Target className="w-5 h-5" />
</div>
<span className="text-[10px] font-bold text-[#5c738e] tracking-wider uppercase font-mono">
air side
</span>
</div>
<div className="mt-3">
<div className="text-3xl font-extrabold text-white">3 / 4</div>
<p className="text-xs text-[#5c738e] mt-1">AHUs running</p>
</div>
</Card>
</div>
{/* --- TELEMETRY SECTION --- */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* Left Card: Chillers & Plant Load Chart */}
<Card className="lg:col-span-7 p-6">
<div className="mb-6">
<h2 className="text-lg font-bold text-white">Chillers</h2>
<p className="text-xs text-[#5c738e] font-mono mt-0.5">live 5 s refresh</p>
</div>
{/* Chillers Table */}
<div className="overflow-x-auto mb-8">
<table className="w-full text-left text-xs">
<thead>
<tr className="text-[#5c738e] font-mono uppercase text-[10px] border-b border-[#162942]/60">
<th className="pb-3 font-normal">UNIT</th>
<th className="pb-3 font-normal">STATUS</th>
<th className="pb-3 font-normal">LOAD</th>
<th className="pb-3 font-normal">COP</th>
<th className="pb-3 font-normal">CHW SUPPLY / RETURN</th>
<th className="pb-3 font-normal">KW</th>
<th className="pb-3 font-normal text-right"></th>
</tr>
</thead>
<tbody className="divide-y divide-[#162942]/40 font-mono">
{/* CH-01 */}
<tr>
<td className="py-3.5 font-bold text-teal-400">CH-01</td>
<td className="py-3.5">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
RUNNING
</span>
</td>
<td className="py-3.5">
<div className="flex items-center gap-2">
<div className="w-16 bg-[#122339] h-2 rounded-full overflow-hidden">
<div className="bg-emerald-400 h-full rounded-full" style={{ width: '72%' }}></div>
</div>
<span className="text-slate-300">72%</span>
</div>
</td>
<td className="py-3.5 font-bold text-emerald-400">5.8</td>
<td className="py-3.5 text-slate-300">6.2 °C / 11.8 °C</td>
<td className="py-3.5 text-slate-300">212</td>
<td className="py-3.5 text-right">
<button className="px-3 py-1 rounded border border-[#162942] text-slate-300 bg-[#0e1c2e] hover:bg-slate-800 text-[11px] font-semibold transition-colors">
Stop
</button>
</td>
</tr>
{/* CH-02 */}
<tr>
<td className="py-3.5 font-bold text-teal-400">CH-02</td>
<td className="py-3.5">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
RUNNING
</span>
</td>
<td className="py-3.5">
<div className="flex items-center gap-2">
<div className="w-16 bg-[#122339] h-2 rounded-full overflow-hidden">
<div className="bg-emerald-400 h-full rounded-full" style={{ width: '64%' }}></div>
</div>
<span className="text-slate-300">64%</span>
</div>
</td>
<td className="py-3.5 font-bold text-amber-400">5.4</td>
<td className="py-3.5 text-slate-300">6.5 °C / 12.1 °C</td>
<td className="py-3.5 text-slate-300">189</td>
<td className="py-3.5 text-right">
<button className="px-3 py-1 rounded border border-[#162942] text-slate-300 bg-[#0e1c2e] hover:bg-slate-800 text-[11px] font-semibold transition-colors">
Stop
</button>
</td>
</tr>
{/* CH-03 */}
<tr>
<td className="py-3.5 font-bold text-teal-400">CH-03</td>
<td className="py-3.5">
<span className="px-2 py-0.5 rounded-full bg-slate-800/60 border border-slate-700/50 text-slate-400 text-[10px] font-bold">
STANDBY
</span>
</td>
<td className="py-3.5">
<div className="flex items-center gap-2">
<div className="w-16 bg-[#122339] h-2 rounded-full overflow-hidden">
<div className="bg-slate-700 h-full rounded-full" style={{ width: '0%' }}></div>
</div>
<span className="text-slate-400">0%</span>
</div>
</td>
<td className="py-3.5 text-slate-500"></td>
<td className="py-3.5 text-slate-500"> / </td>
<td className="py-3.5 text-slate-400">0</td>
<td className="py-3.5 text-right">
<button className="px-3 py-1 rounded border border-[#162942] text-slate-300 bg-[#0e1c2e] hover:bg-slate-800 text-[11px] font-semibold transition-colors">
Start
</button>
</td>
</tr>
</tbody>
</table>
</div>
{/* Plant Load Reusable Bar Chart Component */}
<div>
<h3 className="text-[10px] font-bold
tracking-wider uppercase font-mono mb-4">
PLANT LOAD TODAY
</h3>
<div className="flex-grow flex flex-col justify-end">
<BarChart data={plantLoadData} />
</div>
</div>
</Card>
{/* Right Card: Air Handling Units */}
<Card className="lg:col-span-5 p-6 flex flex-col justify-between">
<div>
<div className="mb-6">
<h2 className="text-lg font-bold text-white">Air handling units</h2>
<p className="text-xs text-[#5c738e] font-mono mt-0.5">supply air fan speed</p>
</div>
{/* AHUs Table */}
<div className="overflow-x-auto">
<table className="w-full text-left text-xs">
<thead>
<tr className="text-[#5c738e] font-mono uppercase text-[10px] border-b border-[#162942]/60">
<th className="pb-3 font-normal">UNIT</th>
<th className="pb-3 font-normal">ZONE</th>
<th className="pb-3 font-normal">STATUS</th>
<th className="pb-3 font-normal">SAT</th>
<th className="pb-3 font-normal">FAN</th>
<th className="pb-3 font-normal">FILTER</th>
</tr>
</thead>
<tbody className="divide-y divide-[#162942]/40 font-mono">
{/* AHU-01 */}
<tr>
<td className="py-4 font-bold text-teal-400 leading-tight">AHU-01</td>
<td className="py-4 text-slate-200 font-sans font-medium leading-tight">Lobby & atrium</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
ON
</span>
</td>
<td className="py-4 text-slate-200">14.2 °C</td>
<td className="py-4 text-slate-200">62%</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
OK
</span>
</td>
</tr>
{/* AHU-04 */}
<tr>
<td className="py-4 font-bold text-teal-400 leading-tight">AHU-04</td>
<td className="py-4 text-slate-200 font-sans font-medium leading-tight">Floors 24</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
ON
</span>
</td>
<td className="py-4 text-slate-200">13.8 °C</td>
<td className="py-4 text-slate-200">71%</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
OK
</span>
</td>
</tr>
{/* AHU-07 */}
<tr>
<td className="py-4 font-bold text-teal-400 leading-tight">AHU-07</td>
<td className="py-4 text-slate-200 font-sans font-medium leading-tight">Floors 57</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
ON
</span>
</td>
<td className="py-4 text-slate-200">15.1 °C</td>
<td className="py-4 text-slate-200">84%</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-amber-950/80 border border-amber-800/50 text-amber-400 text-[10px] font-bold">
REPLACE
</span>
</td>
</tr>
{/* AHU-09 */}
<tr>
<td className="py-4 font-bold text-teal-400 leading-tight">AHU-09</td>
<td className="py-4 text-slate-200 font-sans font-medium leading-tight">
Basement · parking
</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-slate-800/60 border border-slate-700/50 text-slate-400 text-[10px] font-bold">
OFF
</span>
</td>
<td className="py-4 text-slate-500"></td>
<td className="py-4 text-slate-400">0%</td>
<td className="py-4">
<span className="px-2 py-0.5 rounded-full bg-emerald-950/80 border border-emerald-800/50 text-emerald-400 text-[10px] font-bold">
OK
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{/* Footer Warning Notice */}
<div className="pt-6 border-t border-[#162942]/60 mt-6 text-xs text-[#7f93ac] leading-relaxed">
AHU-07 filter ΔP is beyond limit a PPM task can be raised automatically from{' '}
<strong className="text-slate-200 hover:underline cursor-pointer">Alarms & Rules</strong>.
</div>
</Card>
</div>
</div>
);
}