import React, { ReactElement, useEffect, useState } from "react"; import { useGetCachedImportStatisticsQuery } from "../../graphql/generated"; import { useStore } from "../../store"; import { format } from "date-fns"; interface ImportStatsData { totalLocalFiles: number; alreadyImported: number; newFiles: number; percentageImported: string; pendingFiles: number; lastUpdated: string; } /** * Real-time import statistics widget * Displays live statistics from the file watcher and updates via Socket.IO */ export const RealTimeImportStats = (): ReactElement => { const [stats, setStats] = useState(null); const [isConnected, setIsConnected] = useState(false); const getSocket = useStore((state) => state.getSocket); // Fetch initial cached statistics const { data: cachedStats, isLoading, error, refetch, } = useGetCachedImportStatisticsQuery( {}, { refetchOnWindowFocus: false, refetchInterval: false, } ); // Set initial stats from GraphQL query useEffect(() => { if (cachedStats?.getCachedImportStatistics?.success && cachedStats.getCachedImportStatistics.stats) { setStats({ totalLocalFiles: cachedStats.getCachedImportStatistics.stats.totalLocalFiles, alreadyImported: cachedStats.getCachedImportStatistics.stats.alreadyImported, newFiles: cachedStats.getCachedImportStatistics.stats.newFiles, percentageImported: cachedStats.getCachedImportStatistics.stats.percentageImported, pendingFiles: cachedStats.getCachedImportStatistics.stats.pendingFiles, lastUpdated: cachedStats.getCachedImportStatistics.lastUpdated || new Date().toISOString(), }); } }, [cachedStats]); // Setup Socket.IO listener for real-time updates useEffect(() => { const socket = getSocket("/"); const handleConnect = () => { setIsConnected(true); console.log("Real-time import stats: Socket connected"); }; const handleDisconnect = () => { setIsConnected(false); console.log("Real-time import stats: Socket disconnected"); }; const handleStatsUpdate = (data: any) => { console.log("Real-time import stats update received:", data); if (data.stats) { setStats({ totalLocalFiles: data.stats.totalLocalFiles, alreadyImported: data.stats.alreadyImported, newFiles: data.stats.newFiles, percentageImported: data.stats.percentageImported, pendingFiles: data.stats.pendingFiles || 0, lastUpdated: data.lastUpdated || new Date().toISOString(), }); } }; socket.on("connect", handleConnect); socket.on("disconnect", handleDisconnect); socket.on("IMPORT_STATISTICS_UPDATED", handleStatsUpdate); // Check initial connection state if (socket.connected) { setIsConnected(true); } return () => { socket.off("connect", handleConnect); socket.off("disconnect", handleDisconnect); socket.off("IMPORT_STATISTICS_UPDATED", handleStatsUpdate); }; }, [getSocket]); if (isLoading) { return (
Loading statistics...
); } if (error) { return (
Error loading statistics
); } // Handle cache not initialized or no stats available if (!stats || cachedStats?.getCachedImportStatistics?.success === false) { return (

Statistics Cache Initializing

{cachedStats?.getCachedImportStatistics?.message || "The file watcher is starting up. Statistics will appear shortly."}

); } const percentageValue = typeof stats.percentageImported === 'number' ? stats.percentageImported : parseFloat(stats.percentageImported); return (
{/* Header with connection status */}

Real-Time Folder Statistics

{isConnected ? "Live" : "Offline"}
{/* Statistics Grid */}
{stats.totalLocalFiles}
Total Files
{stats.newFiles}
New Files
{stats.alreadyImported}
Imported
{stats.pendingFiles}
Pending
{!isNaN(percentageValue) ? percentageValue.toFixed(1) : '0.0'}%
In Library
{/* Last Updated */}
Last updated: {format(new Date(stats.lastUpdated), "MMM d, yyyy 'at' h:mm:ss a")}
{/* Info message about pending files */} {stats.pendingFiles > 0 && (

{stats.pendingFiles} file{stats.pendingFiles !== 1 ? 's are' : ' is'} being stabilized before import (write in progress).

)} {/* Info message about new files */} {stats.newFiles > 0 && stats.pendingFiles === 0 && (

{stats.newFiles} new file{stats.newFiles !== 1 ? 's are' : ' is'} ready to be imported.

)} {/* All caught up message */} {stats.newFiles === 0 && stats.pendingFiles === 0 && stats.totalLocalFiles > 0 && (

All files in the folder are already imported!

)}
); }; export default RealTimeImportStats;