Configure Completed is added
This commit is contained in:
334
components/dashboard/iotapplication/alarmsRules.tsx
Normal file
334
components/dashboard/iotapplication/alarmsRules.tsx
Normal file
@@ -0,0 +1,334 @@
|
||||
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:00–06: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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user