"use client" import Link from "next/link" import { Timeline, TimelineContent, TimelineDate, TimelineHeader, TimelineIndicator, TimelineItem, TimelineSeparator, TimelineTitle, } from "@/components/reui/timeline" import { Alert, AlertDescription, AlertTitle } from "@/components/reui/alert" import { cn } from "@/lib/utils" import type { EventItem } from "@mmapp/contracts/events" function formatEventAge(iso: string): string { const ts = Date.parse(iso) if (!Number.isFinite(ts)) return "—" const diffMs = Math.max(0, Date.now() - ts) const minutes = Math.floor(diffMs / 60_000) if (minutes < 1) return "сейчас" if (minutes < 60) return `${minutes}м` const hours = Math.floor(minutes / 60) if (hours < 24) return `${hours}ч` const days = Math.floor(hours / 24) return `${days}д` } const LEVEL_DOT: Record = { critical: "border-destructive bg-destructive/20 group-data-completed/timeline-item:border-destructive", warning: "border-warning bg-warning/20 group-data-completed/timeline-item:border-warning", info: "border-info bg-info/20 group-data-completed/timeline-item:border-info", } /** * Compact activity timeline. * Preview: https://reui.io/preview/base/timeline-3 * Docs: https://reui.io/docs/components/base/timeline */ export function DashboardEventsTimeline({ events, loading, error, }: { events: EventItem[] loading?: boolean error?: string | null }) { if (loading && events.length === 0) { return

Загрузка событий…

} if (error && events.length === 0) { return (
События недоступны {error}
) } if (events.length === 0) { return (

Событий пока нет.{" "} Оповещения

) } return ( {events.map((event, index) => ( {formatEventAge(event.createdAt)} {event.title} {event.message} ))} ) }