"use client"; import { useState, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Activity } from "lucide-react"; import Image from "next/image"; const MONITORS = [ { id: 2, name: "Datasaur" }, { id: 6, name: "Audiobookshelf" }, { id: 7, name: "Woodpecker CI" }, { id: 8, name: "Forgejo Git" }, { id: 9, name: "Server dashboard" }, { id: 10, name: "Ratoong" }, { id: 3, name: "Dozzle" }, { id: 12, name: "Observatory" }, { id: 13, name: "Surf hub" }, { id: 11, name: "Anime list" }, { id: 5, name: "Wiki" }, { id: 4, name: "Watchtower" }, ]; const ITEMS_PER_PAGE = 6; const INTERVAL_TIME = 2500; export default function MonitorCard({ isHovered }: { isHovered: boolean }) { const [page, setPage] = useState(0); const totalPages = Math.ceil(MONITORS.length / ITEMS_PER_PAGE); useEffect(() => { let interval: NodeJS.Timeout; if (isHovered) { // Start rotating pages only when hovered interval = setInterval(() => { setPage((p) => (p + 1) % totalPages); }, INTERVAL_TIME); } else { // Defer state reset to avoid "cascading render" error // and allow the fade-out animation to play smoothly const timeout = setTimeout(() => { setPage(0); }, 300); return () => clearTimeout(timeout); } return () => { if (interval) clearInterval(interval); }; }, [isHovered, totalPages]); return (
{/* --- DEFAULT VIEW --- */}
Hetzner Node-01

SYS_STATUS: ONLINE

Architecture

linux/amd64

Provider

Hetzner Cloud

{/* --- REGISTRY VIEW --- */}
{/* HEADER WITH SYNCED TIMER */}

Explore Systems

{String(page + 1).padStart(2, "0")}
); } function RegistrySlider({ page }: { page: number }) { const currentItems = MONITORS.slice( page * ITEMS_PER_PAGE, (page + 1) * ITEMS_PER_PAGE, ); return (
{currentItems.map((m) => (
{m.name}
System Status Average Response Time
))}
); }