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

334 lines
16 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 { useState } from 'react';
import {
BarChart2,
Check,
AlertTriangle,
Clock,
CheckCircle2,
Cpu
} from "lucide-react";
import Button from "@/components/common/button";
import StatCard from "@/components/common/dashStatCard";
export default function AlarmRulesPortal() {
// State for automation rules toggles
const [autoWorkOrder, setAutoWorkOrder] = useState(true);
const [escalateCriticals, setEscalateCriticals] = useState(true);
const [offHoursSetpoint, setOffHoursSetpoint] = useState(true);
const [filterPpmTask, setFilterPpmTask] = useState(false);
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-[10px] font-bold tracking-widest text-emerald-400 uppercase font-mono">
<span>APPLE ONE HQ TOWER</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">IOT</span>
<span className="text-slate-500"></span>
<span className="text-slate-500">ALARMS & RULES</span>
</div>
<h1 className="text-2xl font-bold text-white tracking-tight mt-1">
Alarms & automation rules
</h1>
<p className="text-sm font-medium text-slate-400 mt-2 max-w-xl leading-relaxed">
Acknowledge live alarms, raise work orders in one click, and manage the automation rules that act on telemetry.
</p>
</div>
{/* --- HEADER BUTTONS --- */}
<div className="flex items-center gap-3 self-start md:mt-4">
<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>History</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">
<Check className="w-4 h-4 text-slate-950 stroke-[3]" />
<span>Acknowledge all (3)</span>
</Button>
</div>
</div>
{/* --- STAT CARDS --- */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
{/* Card 1: Critical open */}
<StatCard
variant="icon"
title="Critical open"
value="2"
icon={AlertTriangle}
badgeText="act now"
badgeClassName="text-rose-400 lowercase font-mono font-medium"
iconContainerClassName="bg-rose-950/50 border-rose-800/30 text-rose-400"
/>
{/* Card 2: Warnings open */}
<StatCard
variant="icon"
title="Warnings open"
value="1"
icon={Clock}
badgeText="review"
badgeClassName="text-amber-400 lowercase font-mono font-medium"
iconContainerClassName="bg-amber-950/50 border-amber-800/30 text-amber-400"
/>
{/* Card 3: Acknowledged */}
<StatCard
variant="icon"
title="Acknowledged"
value="2"
icon={CheckCircle2}
badgeText="today"
badgeClassName="text-emerald-400 lowercase font-mono font-medium"
iconContainerClassName="bg-emerald-950/60 border-emerald-800/40 text-emerald-400"
/>
{/* Card 4: Rules active */}
<StatCard
variant="icon"
title="Rules active"
value="3 / 4"
icon={Cpu}
badgeText="automation"
badgeClassName="text-slate-400 lowercase font-mono font-medium"
iconContainerClassName="bg-blue-950/60 border-blue-800/40 text-blue-400"
/>
</div>
{/* --- MAIN CONTENT GRID --- */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* --- LEFT SECTION: ALARMS LIST --- */}
<div className="lg:col-span-7 bg-[#091322]/80 border border-slate-800/80 rounded-xl p-5 shadow-sm">
<div className="mb-4">
<h2 className="text-base font-bold text-white">Alarms</h2>
<p className="text-xs font-mono text-slate-400 mt-0.5">live · newest first</p>
</div>
<div className="divide-y divide-slate-800/60">
{/* Alarm Item 1 */}
<div className="py-3.5 flex items-center justify-between gap-3">
<div className="flex items-start gap-2.5 min-w-0">
<span className="w-2 h-2 rounded-full bg-rose-500 shrink-0 mt-1.5" />
<div className="min-w-0">
<p className="text-sm font-semibold text-slate-100 truncate">
<span className="text-teal-400 font-mono">CH-02</span>
{" · "}
<span>Condenser approach high 4.2 K above design</span>
</p>
<p className="text-xs font-mono text-slate-400 mt-0.5">08:41 · open</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Ack
</Button>
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Work order
</Button>
</div>
</div>
{/* Alarm Item 2 */}
<div className="py-3.5 flex items-center justify-between gap-3">
<div className="flex items-start gap-2.5 min-w-0">
<span className="w-2 h-2 rounded-full bg-amber-500 shrink-0 mt-1.5" />
<div className="min-w-0">
<p className="text-sm font-semibold text-slate-100 truncate">
<span className="text-teal-400 font-mono">AHU-07</span>
{" · "}
<span>Filter ΔP beyond limit replacement due</span>
</p>
<p className="text-xs font-mono text-slate-400 mt-0.5">08:12 · open</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Ack
</Button>
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Work order
</Button>
</div>
</div>
{/* Alarm Item 3 */}
<div className="py-3.5 flex items-center justify-between gap-3">
<div className="flex items-start gap-2.5 min-w-0">
<span className="w-2 h-2 rounded-full bg-rose-500 shrink-0 mt-1.5" />
<div className="min-w-0">
<p className="text-sm font-semibold text-slate-100 truncate">
<span className="text-teal-400 font-mono">CTL-14</span>
{" · "}
<span>Controller offline no heartbeat for 30 min</span>
</p>
<p className="text-xs font-mono text-slate-400 mt-0.5">07:56 · open</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Ack
</Button>
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Work order
</Button>
</div>
</div>
{/* Alarm Item 4 */}
<div className="py-3.5 flex items-center justify-between gap-3">
<div className="flex items-start gap-2.5 min-w-0">
<span className="w-2 h-2 rounded-full bg-amber-500 shrink-0 mt-1.5" />
<div className="min-w-0">
<p className="text-sm font-semibold text-slate-100 truncate">
<span className="text-teal-400 font-mono">SNS-208</span>
{" · "}
<span>CO trending up in open office L3 1,080 ppm</span>
</p>
<p className="text-xs font-mono text-slate-400 mt-0.5">07:30 · acknowledged</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Work order
</Button>
</div>
</div>
{/* Alarm Item 5 */}
<div className="py-3.5 flex items-center justify-between gap-3">
<div className="flex items-start gap-2.5 min-w-0">
<span className="w-2 h-2 rounded-full bg-blue-500 shrink-0 mt-1.5" />
<div className="min-w-0">
<p className="text-sm font-semibold text-slate-100 truncate">
<span className="text-teal-400 font-mono">GW-01</span>
{" · "}
<span>Gateway reconnected after 90 s network drop</span>
</p>
<p className="text-xs font-mono text-slate-400 mt-0.5">06:58 · acknowledged</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Button className="rounded-md border border-slate-700/60 bg-slate-900/40 px-3 py-1 text-xs font-medium text-slate-300 hover:bg-slate-800 hover:text-white transition">
Work order
</Button>
</div>
</div>
</div>
</div>
{/* --- RIGHT SECTION: AUTOMATION RULES --- */}
<div className="lg:col-span-5 bg-[#091322]/80 border border-slate-800/80 rounded-xl p-5 shadow-sm h-fit">
<div className="mb-4">
<h2 className="text-base font-bold text-white">Automation rules</h2>
<p className="text-xs font-mono text-slate-400 mt-0.5">telemetry action</p>
</div>
<div className="divide-y divide-slate-800/60">
{/* Rule 1 */}
<div className="py-3.5 flex items-center justify-between gap-4">
<div>
<h3 className="text-sm font-semibold text-slate-100">
Auto work order on critical alarm
</h3>
<p className="text-xs text-slate-400 mt-0.5">
Raises a Help Desk request with the asset and fault pre-filled
</p>
</div>
<button
type="button"
onClick={() => setAutoWorkOrder(!autoWorkOrder)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
autoWorkOrder ? 'bg-[#2dd4bf]' : 'bg-slate-700'
}`}
>
<span
className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-slate-950 shadow ring-0 transition duration-200 ease-in-out ${
autoWorkOrder ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</div>
{/* Rule 2 */}
<div className="py-3.5 flex items-center justify-between gap-4">
<div>
<h3 className="text-sm font-semibold text-slate-100">
Escalate unacknowledged criticals
</h3>
<p className="text-xs text-slate-400 mt-0.5">
Notifies the escalation matrix after 15 minutes
</p>
</div>
<button
type="button"
onClick={() => setEscalateCriticals(!escalateCriticals)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
escalateCriticals ? 'bg-[#2dd4bf]' : 'bg-slate-700'
}`}
>
<span
className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-slate-950 shadow ring-0 transition duration-200 ease-in-out ${
escalateCriticals ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</div>
{/* Rule 3 */}
<div className="py-3.5 flex items-center justify-between gap-4">
<div>
<h3 className="text-sm font-semibold text-slate-100">
Off-hours setpoint relaxation
</h3>
<p className="text-xs text-slate-400 mt-0.5">
Widens comfort bands 22:0006:00 to save energy
</p>
</div>
<button
type="button"
onClick={() => setOffHoursSetpoint(!offHoursSetpoint)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
offHoursSetpoint ? 'bg-[#2dd4bf]' : 'bg-slate-700'
}`}
>
<span
className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-slate-950 shadow ring-0 transition duration-200 ease-in-out ${
offHoursSetpoint ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</div>
{/* Rule 4 */}
<div className="py-3.5 flex items-center justify-between gap-4">
<div>
<h3 className="text-sm font-semibold text-slate-100">
Filter ΔP PPM task
</h3>
<p className="text-xs text-slate-400 mt-0.5">
Adds a filter change to the next PPM visit automatically
</p>
</div>
<button
type="button"
onClick={() => setFilterPpmTask(!filterPpmTask)}
className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
filterPpmTask ? 'bg-[#2dd4bf]' : 'bg-slate-800'
}`}
>
<span
className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-slate-300 shadow ring-0 transition duration-200 ease-in-out ${
filterPpmTask ? 'translate-x-5 bg-slate-950' : 'translate-x-0'
}`}
/>
</button>
</div>
</div>
</div>
</div>
</div>
);
}