"use client"; import { useState, useMemo } from "react"; import { usePoll } from "@/lib/use-poll"; import type { Container, OverviewStats } from "@/lib/types"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { DataTable, Column } from "@/components/data-table"; import { ContainerLogsModal } from "@/components/container-logs-modal"; import { StatusBadge } from "@/components/status-badge"; import { postAPI } from "@/lib/api"; interface OlaresPod { name: string; namespace: string; status: string; restarts: number; age: string; } export default function InfrastructurePage() { const { data: containers } = usePoll( "/api/containers", 30000 ); const { data: overview } = usePoll( "/api/stats/overview", 60000 ); const { data: pods } = usePoll("/api/olares/pods", 30000); const [logsTarget, setLogsTarget] = useState<{ id: string; name: string; endpoint: string; } | null>(null); const endpoints = useMemo(() => { if (!containers) return []; return [...new Set(containers.map((c) => c.endpoint))]; }, [containers]); const containerColumns: Column[] = [ { key: "name", label: "Name", render: (row) => ( {row.name} ), }, { key: "state", label: "State", render: (row) => ( ), }, { key: "status", label: "Status" }, { key: "endpoint", label: "Endpoint" }, { key: "image", label: "Image", render: (row) => ( {row.image} ), }, ]; const podColumns: Column[] = [ { key: "name", label: "Pod" }, { key: "namespace", label: "Namespace" }, { key: "status", label: "Status", render: (row) => ( ), }, { key: "restarts", label: "Restarts" }, { key: "age", label: "Age" }, ]; const gpu = overview?.gpu; return (

Infrastructure

{/* Container Table */} Containers data={containers ?? []} columns={containerColumns} searchKey="name" filterKey="endpoint" filterOptions={endpoints} actions={(row) => (
)} />
{/* Row 2: Olares Pods + GPU */}
Olares Pods data={pods ?? []} columns={podColumns} searchKey="name" /> GPU Status {!gpu ? (

Loading...

) : gpu.available ? ( <>

{gpu.name}

{gpu.vram_used_mb != null && gpu.vram_total_mb != null && (
VRAM {(gpu.vram_used_mb / 1024).toFixed(1)} /{" "} {(gpu.vram_total_mb / 1024).toFixed(1)} GB
)}

Temperature

{gpu.temp_c ?? "\u2014"}°C

Power

{gpu.power_w ?? "\u2014"}W

Utilization

{gpu.utilization_pct ?? "\u2014"}%

) : (

GPU not available

)}
{/* Logs Modal */} setLogsTarget(null)} />
); }