From 0005c2b348291592df565c158841c16dfb19bd83 Mon Sep 17 00:00:00 2001 From: mbrucedogs Date: Sun, 20 Jul 2025 20:43:10 -0500 Subject: [PATCH] Signed-off-by: mbrucedogs --- src/features/History/History.tsx | 15 ++++-- src/features/Queue/Queue.tsx | 28 ++++++----- src/features/Search/Search.tsx | 27 ++++------- src/hooks/index.ts | 1 + src/hooks/useDebugLogging.ts | 79 ++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 34 deletions(-) create mode 100644 src/hooks/useDebugLogging.ts diff --git a/src/features/History/History.tsx b/src/features/History/History.tsx index f52a091..9996022 100644 --- a/src/features/History/History.tsx +++ b/src/features/History/History.tsx @@ -2,10 +2,9 @@ import React from 'react'; import { IonChip, IonIcon } from '@ionic/react'; import { time } from 'ionicons/icons'; import { InfiniteScrollList, SongItem } from '../../components/common'; -import { useHistory } from '../../hooks'; +import { useHistory, useDebugLogging } from '../../hooks'; import { useAppSelector } from '../../redux'; import { selectHistory, selectIsAdmin } from '../../redux'; -import { debugLog } from '../../utils/logger'; import { formatDate } from '../../utils/dataProcessing'; import type { Song } from '../../types'; @@ -20,9 +19,15 @@ const History: React.FC = () => { const history = useAppSelector(selectHistory); const isAdmin = useAppSelector(selectIsAdmin); const historyCount = Object.keys(history).length; - // Debug logging - debugLog('History component - history count:', historyCount); - debugLog('History component - history items:', historyItems); + + // Use unified debug logging + const { logData } = useDebugLogging({ componentName: 'History' }); + + // Log component data + logData({ + 'history count': historyCount, + 'history items': historyItems, + }); // Render extra content for history items (play date) const renderExtraContent = (item: Song) => { diff --git a/src/features/Queue/Queue.tsx b/src/features/Queue/Queue.tsx index 0c56fd7..760daf6 100644 --- a/src/features/Queue/Queue.tsx +++ b/src/features/Queue/Queue.tsx @@ -8,7 +8,7 @@ import { ActionButton, NumberDisplay, EmptyState } from '../../components/common import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types'; import { Icons } from '../../constants'; import { SongInfoDisplay } from '../../components/common/SongItem'; -import { debugLog } from '../../utils/logger'; +import { useDebugLogging } from '../../hooks'; import type { QueueItem } from '../../types'; const Queue: React.FC = () => { @@ -32,12 +32,17 @@ const Queue: React.FC = () => { const queueCount = useAppSelector(selectQueueLength); - // Debug logging - debugLog('Queue component - queue count:', queueCount); - debugLog('Queue component - queue items:', queueItems); - debugLog('Queue component - canReorder:', canReorder); - debugLog('Queue component - queueMode:', queueMode); - debugLog('Queue component - canDeleteItems:', canDeleteItems); + // Use unified debug logging + const { logData } = useDebugLogging({ componentName: 'Queue' }); + + // Log component data + logData({ + 'queue count': queueCount, + 'queue items': queueItems, + 'canReorder': canReorder, + 'queueMode': queueMode, + 'canDeleteItems': canDeleteItems, + }); // Update list items when queue changes @@ -56,8 +61,7 @@ const Queue: React.FC = () => { }; // Render queue item - const renderQueueItem = (queueItem: QueueItem, index: number) => { - debugLog(`Queue item ${index}: order=${queueItem.order}, key=${queueItem.key}`); + const renderQueueItem = (queueItem: QueueItem) => { const canDelete = canDeleteItems && queueMode === 'delete'; // Only allow delete in delete mode return ( @@ -211,15 +215,15 @@ const Queue: React.FC = () => { {/* Queue List with Reorder */} {canReorder && queueMode === 'reorder' ? ( - {listItems.map((queueItem, index) => ( + {listItems.map((queueItem) => ( - {renderQueueItem(queueItem, index)} + {renderQueueItem(queueItem)} ))} ) : (
- {listItems.map((queueItem, index) => renderQueueItem(queueItem, index))} + {listItems.map((queueItem) => renderQueueItem(queueItem))}
)} diff --git a/src/features/Search/Search.tsx b/src/features/Search/Search.tsx index 654080d..66447ea 100644 --- a/src/features/Search/Search.tsx +++ b/src/features/Search/Search.tsx @@ -1,10 +1,9 @@ import React from 'react'; import { IonSearchbar } from '@ionic/react'; import { InfiniteScrollList, SongItem } from '../../components/common'; -import { useSearch } from '../../hooks'; +import { useSearch, useDebugLogging } from '../../hooks'; import { useAppSelector } from '../../redux'; import { selectIsAdmin, selectSongs } from '../../redux'; -import { debugLog } from '../../utils/logger'; import type { Song } from '../../types'; const Search: React.FC = () => { @@ -19,22 +18,16 @@ const Search: React.FC = () => { const songs = useAppSelector(selectSongs); const songsCount = Object.keys(songs).length; - // Performance monitoring - React.useEffect(() => { - const startTime = performance.now(); - - return () => { - const endTime = performance.now(); - const renderTime = endTime - startTime; - debugLog(`Search component render time: ${renderTime.toFixed(2)}ms`); - }; - }); + // Use unified debug logging + const { logData } = useDebugLogging({ componentName: 'Search' }); - // Debug logging - debugLog('Search component - songs count:', songsCount); - debugLog('Search component - search results:', searchResults); - debugLog('Search component - search term:', searchTerm); - debugLog('Search component - showing:', searchResults.songs.length, 'of', searchResults.count); + // Log component data + logData({ + 'songs count': songsCount, + 'search results': searchResults, + 'search term': searchTerm, + 'showing': `${searchResults.songs.length} of ${searchResults.count}`, + }); return ( <> diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 9f641c1..2649f67 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -13,5 +13,6 @@ export { useSongLists } from './useSongLists'; export { useDisabledSongs } from './useDisabledSongs'; export { useActions } from './useActions'; export { usePagination } from './usePagination'; +export { useDebugLogging } from './useDebugLogging'; export { useSongInfo } from './useSongInfo'; \ No newline at end of file diff --git a/src/hooks/useDebugLogging.ts b/src/hooks/useDebugLogging.ts new file mode 100644 index 0000000..fe0c3ed --- /dev/null +++ b/src/hooks/useDebugLogging.ts @@ -0,0 +1,79 @@ +import { useEffect, useCallback } from 'react'; +import { debugLog } from '../utils/logger'; + +export interface DebugLoggingConfig { + componentName: string; + enableRenderTime?: boolean; + enableDataLogging?: boolean; + enablePerformanceMonitoring?: boolean; +} + +export interface DebugData { + [key: string]: unknown; +} + +export const useDebugLogging = (config: DebugLoggingConfig) => { + const { componentName, enableRenderTime = true, enableDataLogging = true } = config; + + // Performance monitoring for component render time + useEffect(() => { + if (!enableRenderTime) return; + + const startTime = performance.now(); + + return () => { + const endTime = performance.now(); + const renderTime = endTime - startTime; + debugLog(`${componentName} component render time: ${renderTime.toFixed(2)}ms`); + }; + }, [componentName, enableRenderTime]); + + // Log component data + const logData = useCallback((data: DebugData) => { + if (!enableDataLogging) return; + + Object.entries(data).forEach(([key, value]) => { + debugLog(`${componentName} component - ${key}:`, value); + }); + }, [componentName, enableDataLogging]); + + // Log single value + const logValue = useCallback((key: string, value: unknown) => { + if (!enableDataLogging) return; + debugLog(`${componentName} component - ${key}:`, value); + }, [componentName, enableDataLogging]); + + // Log hook data + const logHookData = useCallback((hookName: string, data: DebugData) => { + if (!enableDataLogging) return; + + Object.entries(data).forEach(([key, value]) => { + debugLog(`${hookName} - ${key}:`, value); + }); + }, [enableDataLogging]); + + // Log hook single value + const logHookValue = useCallback((hookName: string, key: string, value: unknown) => { + if (!enableDataLogging) return; + debugLog(`${hookName} - ${key}:`, value); + }, [enableDataLogging]); + + // Log component lifecycle + const logLifecycle = useCallback((event: string, data?: DebugData) => { + if (!enableDataLogging) return; + + if (data) { + debugLog(`${componentName} component - ${event}:`, data); + } else { + debugLog(`${componentName} component - ${event}`); + } + }, [componentName, enableDataLogging]); + + return { + logData, + logValue, + logHookData, + logHookValue, + logLifecycle, + }; +}; \ No newline at end of file