import React, { useEffect, useState } from "react"; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"; import { Card, CardHeader, CardTitle, CardContent } from "./ui/card"; import { Activity } from "lucide-react"; import { cn } from "../lib/utils"; import type { ActivityData } from "@shared/modules/dashboard/dashboard.types"; interface ActivityChartProps { className?: string; data?: ActivityData[]; } export function ActivityChart({ className, data: providedData }: ActivityChartProps) { const [data, setData] = useState([]); // using any[] for the displayTime extension const [isLoading, setIsLoading] = useState(!providedData); const [error, setError] = useState(null); useEffect(() => { if (providedData) { // Process provided data const formatted = providedData.map((item) => ({ ...item, displayTime: new Date(item.hour).getHours().toString().padStart(2, '0') + ':00', })); setData(formatted); return; } let mounted = true; async function fetchActivity() { try { const response = await fetch("/api/stats/activity"); if (!response.ok) throw new Error("Failed to fetch activity data"); const result = await response.json(); if (mounted) { // Normalize data: ensure we have 24 hours format // The API returns { hour: ISOString, commands: number, transactions: number } // We want to format hour to readable time const formatted = result.map((item: ActivityData) => ({ ...item, displayTime: new Date(item.hour).getHours().toString().padStart(2, '0') + ':00', })); // Sort by time just in case, though API should handle it setData(formatted); // Only set loading to false on the first load to avoid flickering setIsLoading(false); } } catch (err) { if (mounted) { console.error(err); setError("Failed to load activity data"); setIsLoading(false); } } } fetchActivity(); // Refresh every 60 seconds const interval = setInterval(fetchActivity, 60000); return () => { mounted = false; clearInterval(interval); }; }, [providedData]); if (error) { return ( {error} ); } return (
24h Activity
{isLoading ? (
) : ( `${value}`} /> )}
); }