diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index 0bdb302f..bb308199 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -37,12 +37,12 @@ export const ModerationQueue = forwardRef((props, ref) => { useRealtimeQueue: adminSettings.getUseRealtimeQueue(), refreshOnTabVisible: adminSettings.getRefreshOnTabVisible(), }), [ - adminSettings.getAdminPanelRefreshMode(), - adminSettings.getAdminPanelPollInterval(), - adminSettings.getAutoRefreshStrategy(), - adminSettings.getPreserveInteractionState(), - adminSettings.getUseRealtimeQueue(), - adminSettings.getRefreshOnTabVisible(), + adminSettings.getAdminPanelRefreshMode, + adminSettings.getAdminPanelPollInterval, + adminSettings.getAutoRefreshStrategy, + adminSettings.getPreserveInteractionState, + adminSettings.getUseRealtimeQueue, + adminSettings.getRefreshOnTabVisible, ]); // Initialize queue manager (replaces all state management, fetchItems, effects) diff --git a/src/hooks/useAdminSettings.ts b/src/hooks/useAdminSettings.ts index d54b12ad..48eaaf6b 100644 --- a/src/hooks/useAdminSettings.ts +++ b/src/hooks/useAdminSettings.ts @@ -3,6 +3,7 @@ import { supabase } from '@/integrations/supabase/client'; import { useAuth } from './useAuth'; import { useUserRole } from './useUserRole'; import { useToast } from './use-toast'; +import { useCallback } from 'react'; interface AdminSetting { id: string; @@ -83,85 +84,85 @@ export function useAdminSettings() { return updateSettingMutation.mutateAsync({ key, value }); }; - // Helper functions for common settings - const getAutoFlagThreshold = () => { + // Helper functions for common settings (memoized with useCallback for stable references) + const getAutoFlagThreshold = useCallback(() => { return parseInt(getSettingValue('moderation.auto_flag_threshold', '3')); - }; + }, [settings]); - const getRequireApproval = () => { + const getRequireApproval = useCallback(() => { const value = getSettingValue('moderation.require_approval', 'true'); return value === true || value === 'true'; - }; + }, [settings]); - const getBanDurations = () => { + const getBanDurations = useCallback(() => { const value = getSettingValue('moderation.ban_durations', ['1d', '7d', '30d', 'permanent']); return Array.isArray(value) ? value : JSON.parse(value || '[]'); - }; + }, [settings]); - const getEmailAlertsEnabled = () => { + const getEmailAlertsEnabled = useCallback(() => { const value = getSettingValue('notifications.email_alerts', 'true'); return value === true || value === 'true'; - }; + }, [settings]); - const getReportThreshold = () => { + const getReportThreshold = useCallback(() => { return parseInt(getSettingValue('notifications.report_threshold', '5')); - }; + }, [settings]); - const getAuditRetentionDays = () => { + const getAuditRetentionDays = useCallback(() => { return parseInt(getSettingValue('system.audit_retention_days', '365')); - }; + }, [settings]); - const getAutoCleanupEnabled = () => { + const getAutoCleanupEnabled = useCallback(() => { const value = getSettingValue('system.auto_cleanup', 'false'); return value === true || value === 'true'; - }; + }, [settings]); - const getAdminPanelRefreshMode = () => { + const getAdminPanelRefreshMode = useCallback(() => { const value = getSettingValue('system.admin_panel_refresh_mode', 'auto'); // Remove quotes if they exist (JSON string stored in DB) return typeof value === 'string' ? value.replace(/"/g, '') : value; - }; + }, [settings]); - const getAdminPanelPollInterval = () => { + const getAdminPanelPollInterval = useCallback(() => { const value = getSettingValue('system.admin_panel_poll_interval', 30); return parseInt(value?.toString() || '30') * 1000; // Convert to milliseconds - }; + }, [settings]); /** * Get auto-refresh strategy setting * Returns: 'merge' | 'replace' | 'notify' */ - const getAutoRefreshStrategy = (): 'merge' | 'replace' | 'notify' => { + const getAutoRefreshStrategy = useCallback((): 'merge' | 'replace' | 'notify' => { const value = getSettingValue('auto_refresh_strategy', 'merge'); const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value; return cleanValue as 'merge' | 'replace' | 'notify'; - }; + }, [settings]); /** * Get preserve interaction state setting * Returns: boolean */ - const getPreserveInteractionState = (): boolean => { + const getPreserveInteractionState = useCallback((): boolean => { const value = getSettingValue('preserve_interaction_state', 'true'); const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value; return cleanValue === 'true' || cleanValue === true; - }; + }, [settings]); - const getNotificationRecipients = () => { + const getNotificationRecipients = useCallback(() => { return getSettingValue('notifications.recipients', []); - }; + }, [settings]); - const getUseRealtimeQueue = (): boolean => { + const getUseRealtimeQueue = useCallback((): boolean => { const value = getSettingValue('system.use_realtime_queue', 'true'); const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value; return cleanValue === 'true' || cleanValue === true; - }; + }, [settings]); - const getRefreshOnTabVisible = (): boolean => { + const getRefreshOnTabVisible = useCallback((): boolean => { const value = getSettingValue('system.refresh_on_tab_visible', 'false'); const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value; return cleanValue === 'true' || cleanValue === true; - }; + }, [settings]); return { settings,