// src/components/dashboard/RouterTableLogic.tsx import { useState, useMemo, useEffect, useCallback } from 'react'; import { RouterData, FilterType } from '../../types'; interface TimeoutInfo { timeoutId: NodeJS.Timeout; startTime: number; } interface AutoHideTimeouts { [key: string]: TimeoutInfo; } export const useRouterTableLogic = (initialRouters: RouterData[] = []) => { const [searchTerm, setSearchTerm] = useState(''); const [expandedRows, setExpandedRows] = useState>(new Set()); const [sortConfig, setSortConfig] = useState<{ key: keyof RouterData; direction: 'asc' | 'desc' } | null>(null); const [timeLeft, setTimeLeft] = useState<{ [key: string]: number }>({}); const [autoHideTimeouts, setAutoHideTimeouts] = useState({}); const AUTO_HIDE_DELAY = 10000; // Update countdown timer useEffect(() => { const interval = setInterval(() => { setTimeLeft(prev => { const now = Date.now(); const updated = { ...prev }; Object.entries(autoHideTimeouts).forEach(([key, info]) => { if (info) { const remaining = Math.max(0, AUTO_HIDE_DELAY - (now - info.startTime)); updated[key] = (remaining / AUTO_HIDE_DELAY) * 100; } }); return updated; }); }, 100); // Cleanup on unmount return () => { clearInterval(interval); Object.values(autoHideTimeouts).forEach(info => { if (info?.timeoutId) { clearTimeout(info.timeoutId); } }); }; }, [autoHideTimeouts]); // Filter and sort data const filteredRouters = useMemo(() => { const routers = Array.isArray(initialRouters) ? initialRouters : []; let processed = [...routers]; if (searchTerm.trim()) { const lowerSearchTerm = searchTerm.toLowerCase().trim(); processed = processed.filter(router => { const searchableFields = ['routerId', 'routerAlias', 'facility']; return searchableFields.some(field => String(router[field as keyof RouterData] || '') .toLowerCase() .includes(lowerSearchTerm) ); }); } if (sortConfig) { processed.sort((a, b) => { const aValue = a[sortConfig.key]; const bValue = b[sortConfig.key]; if (aValue < bValue) return sortConfig.direction === 'asc' ? -1 : 1; if (aValue > bValue) return sortConfig.direction === 'asc' ? 1 : -1; return 0; }); } return processed; }, [initialRouters, searchTerm, sortConfig]); const handleSort = useCallback((key: keyof RouterData) => { setSortConfig(current => ({ key, direction: current?.key === key && current.direction === 'asc' ? 'desc' : 'asc' })); }, []); const toggleRowExpansion = useCallback((rowId: number, section: 'activity' | 'status' | 'disk') => { const key = `${rowId}-${section}`; setExpandedRows(prev => { const next = new Set(prev); if (next.has(key)) { next.delete(key); const existingTimeout = autoHideTimeouts[key]?.timeoutId; if (existingTimeout) { clearTimeout(existingTimeout); setAutoHideTimeouts(prev => { const next = { ...prev }; delete next[key]; return next; }); setTimeLeft(prev => { const next = { ...prev }; delete next[key]; return next; }); } } else { next.add(key); const timeoutId = setTimeout(() => { setExpandedRows(prev => { const next = new Set(prev); next.delete(key); return next; }); setAutoHideTimeouts(prev => { const next = { ...prev }; delete next[key]; return next; }); setTimeLeft(prev => { const next = { ...prev }; delete next[key]; return next; }); }, AUTO_HIDE_DELAY); setAutoHideTimeouts(prev => ({ ...prev, [key]: { timeoutId, startTime: Date.now() } })); setTimeLeft(prev => ({ ...prev, [key]: 100 })); } return next; }); }, [autoHideTimeouts]); const handleExpandedContentHover = useCallback((rowId: number, section: 'activity' | 'status' | 'disk') => { const key = `${rowId}-${section}`; const existingTimeout = autoHideTimeouts[key]?.timeoutId; if (existingTimeout) { clearTimeout(existingTimeout); const timeoutId = setTimeout(() => { setExpandedRows(prev => { const next = new Set(prev); next.delete(key); return next; }); setAutoHideTimeouts(prev => { const next = { ...prev }; delete next[key]; return next; }); setTimeLeft(prev => { const next = { ...prev }; delete next[key]; return next; }); }, AUTO_HIDE_DELAY); setAutoHideTimeouts(prev => ({ ...prev, [key]: { timeoutId, startTime: Date.now() } })); setTimeLeft(prev => ({ ...prev, [key]: 100 })); } }, [autoHideTimeouts]); return { routers: filteredRouters, totalRouters: initialRouters.length, searchTerm, setSearchTerm, expandedRows, timeLeft, handleSort, toggleRowExpansion, handleExpandedContentHover }; };