import { AppSidebar } from "@/components/app-sidebar"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Separator } from "@/components/ui/separator"; import { SidebarInset, SidebarProvider, SidebarTrigger, } from "@/components/ui/sidebar"; import { useEffect, useState } from "react"; import axios from "axios"; import { Card, CardHeader } from "@/components/ui/card"; import * as Tooltip from "@radix-ui/react-tooltip"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Pagination, PaginationContent, PaginationItem, PaginationPrevious, PaginationNext, PaginationLink, } from "@/components/ui/pagination"; const timeFormats = { 1: (timestamp: string) => new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }), 2: (timestamp: string) => { const start = new Date(timestamp); const end = new Date(start.getTime() + 3 * 60 * 60 * 1000); return `${start.toLocaleDateString([], { day: '2-digit', month: 'short' })} ${start.getHours().toString().padStart(2, '0')}:00 - ${end.getHours().toString().padStart(2, '0')}:00`; }, 3: (timestamp: string) => new Date(timestamp).toLocaleDateString([], { day: '2-digit', month: 'short' }) }; const minBoxWidths = { 1: 24, 2: 24, 3: 24 }; interface UptimeData { appName: string; appId: number; uptimeSummary: { timestamp: string; missing: boolean; online: boolean | null; }[]; } interface PaginationData { currentPage: number; totalPages: number; totalItems: number; } export default function Uptime() { const [data, setData] = useState([]); const [timespan, setTimespan] = useState<1 | 2 | 3>(1); const [pagination, setPagination] = useState({ currentPage: 1, totalPages: 1, totalItems: 0 }); const [isLoading, setIsLoading] = useState(false); const getData = async (selectedTimespan: number, page: number) => { setIsLoading(true); try { const response = await axios.post<{ data: UptimeData[]; pagination: PaginationData; }>("/api/applications/uptime", { timespan: selectedTimespan, page }); setData(response.data.data); setPagination(response.data.pagination); } catch (error) { console.error("Error:", error); setData([]); setPagination({ currentPage: 1, totalPages: 1, totalItems: 0 }); } finally { setIsLoading(false); } }; const handlePrevious = () => { const newPage = Math.max(1, pagination.currentPage - 1); setPagination(prev => ({...prev, currentPage: newPage})); getData(timespan, newPage); }; const handleNext = () => { const newPage = Math.min(pagination.totalPages, pagination.currentPage + 1); setPagination(prev => ({...prev, currentPage: newPage})); getData(timespan, newPage); }; useEffect(() => { getData(timespan, 1); }, [timespan]); return (
/ My Infrastructure Uptime
Uptime
{isLoading ? (
Loading...
) : ( data.map((app) => { const reversedSummary = [...app.uptimeSummary].reverse(); const startTime = reversedSummary[0]?.timestamp; const endTime = reversedSummary[reversedSummary.length - 1]?.timestamp; return (
{app.appName}
{startTime ? timeFormats[timespan](startTime) : ""} {endTime ? timeFormats[timespan](endTime) : ""}
{reversedSummary.map((entry) => (

{timespan === 2 ? ( timeFormats[2](entry.timestamp) ) : ( new Date(entry.timestamp).toLocaleString([], { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: timespan === 3 ? undefined : '2-digit', hour12: false }) )}

{entry.missing ? "No data" : entry.online ? "Online" : "Offline"}

))}
); }) )}
{pagination.totalItems > 0 && !isLoading && (
{pagination.currentPage}
)}
); }