import React, { useState, useCallback } from 'react'; import { Box, Typography, Collapse, IconButton, Tooltip, useTheme, alpha, Card, CardContent, Stack, Alert, } from '@mui/material'; import { ExpandMore as ExpandMoreIcon, ExpandLess as ExpandLessIcon, Speed as SpeedIcon, Folder as FolderIcon, TextSnippet as FileIcon, Storage as StorageIcon, CheckCircle as CheckCircleIcon, Error as ErrorIcon, } from '@mui/icons-material'; import { SyncProgressInfo } from '../../services/api'; import { useSyncProgress } from '../../hooks/useSyncProgress'; import { ConnectionStatus } from '../../services/syncProgress'; import { ConnectionStatusIndicator } from './ConnectionStatusIndicator'; import { ProgressStatistics } from './ProgressStatistics'; import { SyncProgressManager } from '../../services/syncProgress'; interface SyncProgressDisplayProps { sourceId: string; sourceName: string; isVisible: boolean; onClose?: () => void; manager?: SyncProgressManager; } export const SyncProgressDisplay: React.FC = ({ sourceId, sourceName, isVisible, onClose, manager, }) => { const theme = useTheme(); const [isExpanded, setIsExpanded] = useState(true); // Handle WebSocket connection errors const handleWebSocketError = useCallback((error: Error) => { console.error('WebSocket connection error in SyncProgressDisplay:', error); }, []); // Handle connection status changes const handleConnectionStatusChange = useCallback((status: ConnectionStatus) => { console.log(`Connection status changed to: ${status}`); }, []); // Use the sync progress hook const { progressInfo, connectionStatus, isConnected, reconnect, disconnect, } = useSyncProgress({ sourceId, enabled: isVisible && !!sourceId, onError: handleWebSocketError, onConnectionStatusChange: handleConnectionStatusChange, manager, }); const getPhaseColor = (phase: string) => { switch (phase) { case 'initializing': case 'evaluating': return theme.palette.info.main; case 'discovering_directories': case 'discovering_files': return theme.palette.warning.main; case 'processing_files': return theme.palette.primary.main; case 'saving_metadata': return theme.palette.secondary.main; case 'completed': return theme.palette.success.main; case 'failed': return theme.palette.error.main; default: return theme.palette.grey[500]; } }; const getPhaseIcon = (phase: string) => { switch (phase) { case 'discovering_directories': return ; case 'discovering_files': case 'processing_files': return ; case 'saving_metadata': return ; case 'completed': return ; case 'failed': return ; default: return ; } }; if (!isVisible || (!progressInfo && connectionStatus === 'disconnected' && !isConnected)) { return null; } const phaseColor = progressInfo ? getPhaseColor(progressInfo.phase) : theme.palette.grey[500]; return ( {progressInfo && ( {getPhaseIcon(progressInfo.phase)} )} {sourceName} - Sync Progress {progressInfo && ( {progressInfo.phase_description} )} setIsExpanded(!isExpanded)} size="small" > {isExpanded ? : } {progressInfo ? ( ) : ( Waiting for sync progress information... )} ); }; export default SyncProgressDisplay;