'use client'; import React, { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Activity } from 'lucide-react'; 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; export default function MonitorRegistry({ isHovered }: { isHovered: boolean }) { const [page, setPage] = useState(0); const totalPages = Math.ceil(MONITORS.length / ITEMS_PER_PAGE); useEffect(() => { let interval: NodeJS.Timeout | null = null; if (isHovered && totalPages > 1) { // Only start the interval if we are hovered interval = setInterval(() => { setPage((prev) => (prev + 1) % totalPages); }, 4000); } // This cleanup function runs whenever isHovered changes // or the component unmounts. return () => { if (interval) clearInterval(interval); // Move the reset here so it happens "after" the effect cycle if (!isHovered) { setPage(0); } }; }, [isHovered, totalPages]); const currentMonitors = MONITORS.slice(page * ITEMS_PER_PAGE, (page + 1) * ITEMS_PER_PAGE); return ( <> {/* Default View */}
{/* Header Section */}
Hetzner Node-01

SYS_STATUS:

Online
{/* Added "Server Specs" to fill space and match the style of "The Architect" */}

Architecture

linux/amd64

Provider

Hetzner Cloud

{/* Hover View */} {/* Hover View: Automated Carousel */}

Service Registry

{/* Increased height slightly to 200px and removed 'justify-center' from parent */}
{currentMonitors.map((m) => (
{m.name}
{/* Scale badges slightly */} up ms
))}
); }