"use client"; import Link from "next/link"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { cn } from "@/lib/utils"; import { acknowledgeAlarm, type Alarm } from "@/lib/api"; import { useState } from "react"; import { ChevronRight } from "lucide-react"; interface Props { alarms: Alarm[]; loading?: boolean; onAcknowledge?: () => void; onAlarmClick?: (alarm: Alarm) => void; } const severityStyles: Record = { critical: { badge: "bg-destructive/20 text-destructive border-destructive/30", dot: "bg-destructive" }, warning: { badge: "bg-amber-500/20 text-amber-400 border-amber-500/30", dot: "bg-amber-400" }, info: { badge: "bg-primary/20 text-primary border-primary/30", dot: "bg-primary" }, }; function timeAgo(iso: string) { const secs = Math.floor((Date.now() - new Date(iso).getTime()) / 1000); if (secs < 60) return `${secs}s ago`; if (secs < 3600) return `${Math.floor(secs / 60)}m ago`; return `${Math.floor(secs / 3600)}h ago`; } export function AlarmFeed({ alarms, loading, onAcknowledge, onAlarmClick }: Props) { const [acking, setAcking] = useState(null); async function handleAck(id: number) { setAcking(id); try { await acknowledgeAlarm(id); onAcknowledge?.(); } catch { /* ignore */ } finally { setAcking(null); } } const activeCount = alarms.filter((a) => a.state === "active").length; return (
Active Alarms
{!loading && ( 0 ? "destructive" : "outline"} className="text-[10px] h-4 px-1.5"> {activeCount > 0 ? `${activeCount} active` : "All clear"} )} View all →
{loading ? ( ) : alarms.length === 0 ? (
No active alarms
) : ( alarms.map((alarm) => { const style = severityStyles[alarm.severity] ?? severityStyles.info; const clickable = !!onAlarmClick; const locationLabel = [alarm.rack_id, alarm.room_id].find(Boolean); return (
onAlarmClick?.(alarm)} className={cn( "flex gap-2.5 group rounded-md px-1 py-1 -mx-1 transition-colors", clickable && "cursor-pointer hover:bg-muted/40" )} >

{alarm.message}

{locationLabel && ( {locationLabel} )} {locationLabel && ·} {timeAgo(alarm.triggered_at)}
{alarm.severity} {alarm.state === "active" && ( )} {clickable && ( )}
); }) )}
); }