diff --git a/frontend/src/pages/Settings/DebugStatus.tsx b/frontend/src/pages/Settings/DebugStatus.tsx index 6ddff77e..714a0730 100644 --- a/frontend/src/pages/Settings/DebugStatus.tsx +++ b/frontend/src/pages/Settings/DebugStatus.tsx @@ -1,7 +1,11 @@ -import { useState, useEffect, useCallback } from "react"; +import React, { useState, useEffect, useCallback, useRef } from "react"; import PageMeta from "../../components/common/PageMeta"; import ComponentCard from "../../components/common/ComponentCard"; +import SiteAndSectorSelector from "../../components/common/SiteAndSectorSelector"; +import WordPressIntegrationDebug from "./WordPressIntegrationDebug"; import { API_BASE_URL, fetchAPI } from "../../services/api"; +import { useSiteStore } from "../../store/siteStore"; +import { useToast } from "../../components/ui/toast/ToastContainer"; interface HealthCheck { name: string; @@ -10,6 +14,9 @@ interface HealthCheck { message?: string; details?: string; lastChecked?: string; + step?: string; + payloadKeys?: string[]; + responseCode?: number; } interface ModuleHealth { @@ -18,39 +25,105 @@ interface ModuleHealth { checks: HealthCheck[]; } +interface SyncEvent { + id: string; + timestamp: string; + direction: 'πŸ“€ IGNY8 β†’ WP' | 'πŸ“₯ WP β†’ IGNY8'; + trigger: string; + contentId?: number; + taskId?: number; + status: 'success' | 'partial' | 'failed'; + steps: SyncEventStep[]; + payload?: any; + response?: any; +} + +interface SyncEventStep { + step: string; + file: string; + status: 'success' | 'warning' | 'failed' | 'skipped'; + details: string; + error?: string; + duration?: number; +} + +interface DataSyncValidation { + field: string; + sentByIgny8: boolean; + receivedByWP: boolean; + storedInWP: boolean; + verifiedInWPPost: boolean; + error?: string; +} + +interface IntegrationHealth { + overall: 'healthy' | 'warning' | 'error'; + lastSyncIgny8ToWP?: string; + lastSyncWPToIgny8?: string; + lastSiteMetadataCheck?: string; + wpApiReachable: boolean; + wpStatusEndpoint: boolean; + wpMetadataEndpoint: boolean; + apiKeyValid: boolean; + jwtTokenValid: boolean; +} + const getStatusColor = (status: string) => { switch (status) { - case 'healthy': return 'text-green-600 dark:text-green-400'; - case 'warning': return 'text-yellow-600 dark:text-yellow-400'; - case 'error': return 'text-red-600 dark:text-red-400'; + case 'healthy': + case 'success': return 'text-green-600 dark:text-green-400'; + case 'warning': + case 'partial': return 'text-yellow-600 dark:text-yellow-400'; + case 'error': + case 'failed': return 'text-red-600 dark:text-red-400'; case 'checking': return 'text-blue-600 dark:text-blue-400'; + case 'skipped': return 'text-gray-600 dark:text-gray-400'; default: return 'text-gray-600 dark:text-gray-400'; } }; const getStatusBadge = (status: string) => { switch (status) { - case 'healthy': return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'; - case 'warning': return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400'; - case 'error': return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'; + case 'healthy': + case 'success': return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'; + case 'warning': + case 'partial': return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400'; + case 'error': + case 'failed': return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'; case 'checking': return 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400'; + case 'skipped': return 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400'; default: return 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400'; } }; const getStatusIcon = (status: string) => { switch (status) { - case 'healthy': return 'βœ“'; - case 'warning': return '⚠'; - case 'error': return 'βœ—'; + case 'healthy': + case 'success': return 'βœ“'; + case 'warning': + case 'partial': return '⚠'; + case 'error': + case 'failed': return 'βœ—'; case 'checking': return '⟳'; + case 'skipped': return 'β€”'; default: return '?'; } }; export default function DebugStatus() { - const [moduleHealths, setModuleHealths] = useState([]); + const { activeSite } = useSiteStore(); + const toast = useToast(); + + // Tab navigation state + const [activeTab, setActiveTab] = useState<'system-health' | 'wp-integration'>('system-health'); + + // Debug state + const [debugEnabled, setDebugEnabled] = useState(false); const [loading, setLoading] = useState(false); + const [pollingInterval, setPollingInterval] = useState(null); + + // Data state + const [moduleHealths, setModuleHealths] = useState([]); // Helper to get auth token const getAuthToken = () => { @@ -70,8 +143,14 @@ export default function DebugStatus() { return token; }; - // Helper to make authenticated API calls + // Helper to make authenticated API calls with debug awareness const apiCall = async (path: string, method: string = 'GET', body?: any) => { + // Skip API calls if debug is disabled (unless it's essential) + if (!debugEnabled && !path.includes('/debug-status/')) { + console.log('[DEBUG] Skipping API call - debug disabled:', path); + return { response: null, data: null }; + } + const token = getAuthToken(); const headers: HeadersInit = { 'Content-Type': 'application/json', @@ -91,11 +170,266 @@ export default function DebugStatus() { options.body = JSON.stringify(body); } - const response = await fetch(`${API_BASE_URL}${path}`, options); - const data = await response.json(); - return { response, data }; + try { + if (debugEnabled) { + console.log('[DEBUG] API Call:', method, path, body ? { body } : {}); + } + + const response = await fetch(`${API_BASE_URL}${path}`, options); + const data = await response.json(); + + if (debugEnabled) { + console.log('[DEBUG] API Response:', response.status, data); + } + + return { response, data }; + } catch (error) { + if (debugEnabled) { + console.error('[DEBUG] API Error:', error); + } + throw error; + } }; + // Toggle debug mode + const toggleDebugMode = async (enabled: boolean) => { + if (!activeSite) { + toast.error('Please select a site first'); + return; + } + + try { + setLoading(true); + + // Set local debug state first for immediate UI response + setDebugEnabled(enabled); + + if (enabled) { + console.log('[DEBUG] 🎯 Debug mode ENABLED for site:', activeSite.name); + toast.success('Debug mode enabled - verbose logging started'); + + // Start polling for updates + startPolling(); + + // Trigger debug mode on WordPress plugin if integrated + if (activeSite.id) { + await apiCall(`/integration/integrations/${activeSite.id}/trigger-debug/`, 'POST', { + debug_enabled: true + }); + } + } else { + console.log('[DEBUG] πŸ”’ Debug mode DISABLED'); + toast.info('Debug mode disabled - reduced logging'); + + // Stop polling + stopPolling(); + + // Disable debug on WordPress + if (activeSite.id) { + await apiCall(`/integration/integrations/${activeSite.id}/trigger-debug/`, 'POST', { + debug_enabled: false + }); + } + } + } catch (error) { + console.error('[DEBUG] Failed to toggle debug mode:', error); + toast.error('Failed to toggle debug mode'); + setDebugEnabled(!enabled); // Revert + } finally { + setLoading(false); + } + }; + + // Start polling for debug data + const startPolling = () => { + if (pollingInterval) return; + + const interval = setInterval(() => { + if (debugEnabled && activeSite) { + loadDebugData(); + } + }, 5000); // Poll every 5 seconds when debug is enabled + + setPollingInterval(interval); + console.log('[DEBUG] ⏰ Started polling for debug updates'); + }; + + // Stop polling + const stopPolling = () => { + if (pollingInterval) { + clearInterval(pollingInterval); + setPollingInterval(null); + console.log('[DEBUG] ⏸️ Stopped polling'); + } + }; + + // Load all debug data + const loadDebugData = useCallback(async () => { + if (!activeSite || !debugEnabled) return; + + try { + setLoading(true); + console.log('[DEBUG] πŸ“Š Loading debug data for site:', activeSite.name); + + // Load integration health + await loadIntegrationHealth(); + + // Load sync events + await loadSyncEvents(); + + // Load validation data + await loadDataValidation(); + + // Load module health (existing logic) + await checkAllModules(); + + console.log('[DEBUG] βœ… Debug data loaded successfully'); + } catch (error) { + console.error('[DEBUG] ❌ Failed to load debug data:', error); + if (debugEnabled) { + toast.error('Failed to load debug data'); + } + } finally { + setLoading(false); + } + }, [activeSite, debugEnabled]); + + // Load integration health + const loadIntegrationHealth = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/`); + + if (data?.success) { + setIntegrationHealth(data.data.health); + console.log('[DEBUG] πŸ’š Integration health loaded'); + } + } catch (error) { + console.error('[DEBUG] Failed to load integration health:', error); + } + }; + + // Load sync events + const loadSyncEvents = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/?include_events=true`); + + if (data?.success && data.data?.events) { + setSyncEvents(data.data.events); + console.log('[DEBUG] πŸ“œ Loaded', data.data.events.length, 'sync events'); + } + } catch (error) { + console.error('[DEBUG] Failed to load sync events:', error); + } + }; + + // Load data validation matrix + const loadDataValidation = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/?include_validation=true`); + + if (data?.success && data.data?.validation) { + setDataValidation(data.data.validation); + console.log('[DEBUG] 🧩 Loaded data validation matrix'); + } + } catch (error) { + console.error('[DEBUG] Failed to load data validation:', error); + } + }; + + // Interactive tools + const testConnection = async () => { + if (!activeSite) return; + + try { + setLoading(true); + console.log('[DEBUG] πŸ”§ Testing connection to WordPress...'); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/test-connection/`, 'POST'); + + if (data?.success) { + toast.success('Connection test successful'); + await loadIntegrationHealth(); // Refresh health data + } else { + toast.error('Connection test failed: ' + data?.message); + } + } catch (error) { + console.error('[DEBUG] Connection test error:', error); + toast.error('Connection test failed'); + } finally { + setLoading(false); + } + }; + + const resyncSiteMetadata = async () => { + if (!activeSite) return; + + try { + setLoading(true); + console.log('[DEBUG] πŸ”„ Re-syncing site metadata...'); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/resync-metadata/`, 'POST'); + + if (data?.success) { + toast.success('Site metadata re-synced successfully'); + await loadDebugData(); // Refresh all data + } else { + toast.error('Re-sync failed: ' + data?.message); + } + } catch (error) { + console.error('[DEBUG] Metadata resync error:', error); + toast.error('Metadata re-sync failed'); + } finally { + setLoading(false); + } + }; + + const validatePostSync = async (taskId?: number) => { + if (!activeSite) return; + + const id = taskId || prompt('Enter Task ID to validate:'); + if (!id) return; + + try { + setLoading(true); + console.log('[DEBUG] πŸ” Validating post sync for task:', id); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/validate-content/${id}/`); + + if (data?.success) { + toast.success('Post validation completed'); + setDataValidation(data.data.validation || []); + } else { + toast.error('Validation failed: ' + data?.message); + } + } catch (error) { + console.error('[DEBUG] Post validation error:', error); + toast.error('Post validation failed'); + } finally { + setLoading(false); + } + }; + + // Effects + useEffect(() => { + // Load initial data when site changes + if (activeSite && debugEnabled) { + loadDebugData(); + } + }, [activeSite, debugEnabled]); + + useEffect(() => { + // Cleanup polling on unmount + return () => { + stopPolling(); + }; + }, []); + // Check database schema field mappings (the issues we just fixed) const checkDatabaseSchemaMapping = useCallback(async (): Promise => { try { @@ -569,7 +903,38 @@ export default function DebugStatus() { - {/* Overall Health Summary */} + {/* Tab Navigation */} +
+
+ +
+
+ + {/* Tab Content */} + {activeTab === 'system-health' ? ( +
+ {/* Overall Health Summary */} @@ -750,6 +1115,11 @@ export default function DebugStatus() {
+ + ) : ( + // WordPress Integration Debug Tab + + )} ); diff --git a/frontend/src/pages/Settings/WordPressIntegrationDebug.tsx b/frontend/src/pages/Settings/WordPressIntegrationDebug.tsx new file mode 100644 index 00000000..abbfaeb3 --- /dev/null +++ b/frontend/src/pages/Settings/WordPressIntegrationDebug.tsx @@ -0,0 +1,672 @@ +import React, { useState, useEffect, useCallback } from 'react'; +import { + CheckCircle, + XCircle, + AlertTriangle, + Loader2, + Activity, + Info, + Clock, + Globe, + RefreshCw, + TestTube, + Wrench, + Database +} from 'lucide-react'; +import { toast } from 'react-hot-toast'; +import SiteAndSectorSelector from '../../components/common/SiteAndSectorSelector'; +import { useSiteStore } from '../../store/siteStore'; + +// Types for WordPress integration debugging +interface IntegrationHealth { + api_status: 'healthy' | 'error'; + api_message: string; + last_api_check: string; + plugin_active: boolean; + plugin_version: string; + debug_mode: boolean; + sync_healthy: boolean; + pending_syncs: number; + last_sync: string | null; +} + +interface SyncEvent { + type: 'sync' | 'error' | 'webhook' | 'debug'; + action: string; + description: string; + timestamp: string; + details?: any; +} + +interface DataValidation { + field_name: string; + igny8_value: string; + wp_value: string; + matches: boolean; + error?: string; +} + +const API_BASE_URL = process.env.NODE_ENV === 'production' + ? 'https://app.igny8.com/api' + : 'http://localhost:8000/api'; + +export default function WordPressIntegrationDebug() { + // State + const [debugEnabled, setDebugEnabled] = useState(false); + const [loading, setLoading] = useState(false); + const [pollingInterval, setPollingInterval] = useState(null); + const [integrationHealth, setIntegrationHealth] = useState(null); + const [syncEvents, setSyncEvents] = useState([]); + const [dataValidation, setDataValidation] = useState([]); + + // Get active site from store + const { activeSite } = useSiteStore(); + + // Helper to get auth token + const getAuthToken = () => { + const token = localStorage.getItem('auth_token') || + (() => { + try { + const authStorage = localStorage.getItem('auth-storage'); + if (authStorage) { + const parsed = JSON.parse(authStorage); + return parsed?.state?.token || ''; + } + } catch (e) { + // Ignore parsing errors + } + return ''; + })(); + return token; + }; + + // Helper to make authenticated API calls with debug awareness + const apiCall = async (path: string, method: string = 'GET', body?: any) => { + // Skip API calls if debug is disabled (unless it's essential) + if (!debugEnabled && !path.includes('/debug-status/')) { + console.log('[WP-DEBUG] Skipping API call - debug disabled:', path); + return { response: null, data: null }; + } + + const token = getAuthToken(); + const headers: HeadersInit = { + 'Content-Type': 'application/json', + }; + + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + + const options: RequestInit = { + method, + headers, + credentials: 'include', + }; + + if (body && method !== 'GET') { + options.body = JSON.stringify(body); + } + + try { + if (debugEnabled) { + console.log('[WP-DEBUG] API Call:', method, path, body ? { body } : {}); + } + + const response = await fetch(`${API_BASE_URL}${path}`, options); + const data = await response.json(); + + if (debugEnabled) { + console.log('[WP-DEBUG] API Response:', response.status, data); + } + + return { response, data }; + } catch (error) { + if (debugEnabled) { + console.error('[WP-DEBUG] API Error:', error); + } + throw error; + } + }; + + // Toggle debug mode + const toggleDebugMode = async (enabled: boolean) => { + if (!activeSite) { + toast.error('Please select a site first'); + return; + } + + try { + setLoading(true); + + // Set local debug state first for immediate UI response + setDebugEnabled(enabled); + + if (enabled) { + console.log('[WP-DEBUG] 🎯 WordPress Debug mode ENABLED for site:', activeSite.name); + toast.success('WordPress debug mode enabled - verbose logging started'); + + // Start polling for updates + startPolling(); + + // Trigger debug mode on WordPress plugin if integrated + if (activeSite.id) { + await apiCall(`/integration/integrations/${activeSite.id}/trigger-debug/`, 'POST', { + debug_enabled: true + }); + } + } else { + console.log('[WP-DEBUG] πŸ”’ WordPress Debug mode DISABLED'); + toast.info('WordPress debug mode disabled - reduced logging'); + + // Stop polling + stopPolling(); + + // Disable debug on WordPress + if (activeSite.id) { + await apiCall(`/integration/integrations/${activeSite.id}/trigger-debug/`, 'POST', { + debug_enabled: false + }); + } + } + } catch (error) { + console.error('[WP-DEBUG] Failed to toggle debug mode:', error); + toast.error('Failed to toggle WordPress debug mode'); + setDebugEnabled(!enabled); // Revert + } finally { + setLoading(false); + } + }; + + // Start polling for debug data + const startPolling = () => { + if (pollingInterval) return; + + const interval = setInterval(() => { + if (debugEnabled && activeSite) { + loadDebugData(); + } + }, 5000); // Poll every 5 seconds when debug is enabled + + setPollingInterval(interval); + console.log('[WP-DEBUG] ⏰ Started polling for WordPress debug updates'); + }; + + // Stop polling + const stopPolling = () => { + if (pollingInterval) { + clearInterval(pollingInterval); + setPollingInterval(null); + console.log('[WP-DEBUG] ⏸️ Stopped polling'); + } + }; + + // Load all debug data + const loadDebugData = useCallback(async () => { + if (!activeSite || !debugEnabled) return; + + try { + setLoading(true); + console.log('[WP-DEBUG] πŸ“Š Loading WordPress debug data for site:', activeSite.name); + + // Load integration health + await loadIntegrationHealth(); + + // Load sync events + await loadSyncEvents(); + + // Load validation data + await loadDataValidation(); + + console.log('[WP-DEBUG] βœ… WordPress debug data loaded successfully'); + } catch (error) { + console.error('[WP-DEBUG] ❌ Failed to load WordPress debug data:', error); + if (debugEnabled) { + toast.error('Failed to load WordPress debug data'); + } + } finally { + setLoading(false); + } + }, [activeSite, debugEnabled]); + + // Load integration health + const loadIntegrationHealth = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/`); + + if (data?.success) { + setIntegrationHealth(data.data.health); + console.log('[WP-DEBUG] πŸ’š Integration health loaded'); + } + } catch (error) { + console.error('[WP-DEBUG] Failed to load integration health:', error); + } + }; + + // Load sync events + const loadSyncEvents = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/?include_events=true`); + + if (data?.success && data.data?.events) { + setSyncEvents(data.data.events); + console.log('[WP-DEBUG] πŸ“œ Loaded', data.data.events.length, 'WordPress sync events'); + } + } catch (error) { + console.error('[WP-DEBUG] Failed to load sync events:', error); + } + }; + + // Load data validation matrix + const loadDataValidation = async () => { + if (!activeSite) return; + + try { + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/debug-status/?include_validation=true`); + + if (data?.success && data.data?.validation) { + setDataValidation(data.data.validation); + console.log('[WP-DEBUG] 🧩 Loaded WordPress data validation matrix'); + } + } catch (error) { + console.error('[WP-DEBUG] Failed to load data validation:', error); + } + }; + + // Interactive tools + const testConnection = async () => { + if (!activeSite) return; + + try { + setLoading(true); + console.log('[WP-DEBUG] πŸ”§ Testing connection to WordPress...'); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/test-connection/`, 'POST'); + + if (data?.success) { + toast.success('WordPress connection test successful'); + await loadIntegrationHealth(); // Refresh health data + } else { + toast.error('WordPress connection test failed: ' + data?.message); + } + } catch (error) { + console.error('[WP-DEBUG] Connection test error:', error); + toast.error('WordPress connection test failed'); + } finally { + setLoading(false); + } + }; + + const resyncSiteMetadata = async () => { + if (!activeSite) return; + + try { + setLoading(true); + console.log('[WP-DEBUG] πŸ”„ Re-syncing WordPress site metadata...'); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/resync-metadata/`, 'POST'); + + if (data?.success) { + toast.success('WordPress site metadata re-synced successfully'); + await loadDebugData(); // Refresh all data + } else { + toast.error('WordPress re-sync failed: ' + data?.message); + } + } catch (error) { + console.error('[WP-DEBUG] Metadata resync error:', error); + toast.error('WordPress metadata re-sync failed'); + } finally { + setLoading(false); + } + }; + + const validatePostSync = async (taskId?: number) => { + if (!activeSite) return; + + const id = taskId || prompt('Enter Task ID to validate WordPress sync:'); + if (!id) return; + + try { + setLoading(true); + console.log('[WP-DEBUG] πŸ” Validating WordPress post sync for task:', id); + + const { data } = await apiCall(`/integration/integrations/${activeSite.id}/validate-content/${id}/`); + + if (data?.success) { + toast.success('WordPress post validation completed'); + setDataValidation(data.data.validation || []); + } else { + toast.error('WordPress validation failed: ' + data?.message); + } + } catch (error) { + console.error('[WP-DEBUG] Post validation error:', error); + toast.error('WordPress post validation failed'); + } finally { + setLoading(false); + } + }; + + // Effects + useEffect(() => { + // Load initial data when site changes + if (activeSite && debugEnabled) { + loadDebugData(); + } + }, [activeSite, debugEnabled, loadDebugData]); + + useEffect(() => { + // Cleanup polling on unmount + return () => { + stopPolling(); + }; + }, []); + + return ( +
+ {/* Debug Header with Site Selector and Toggle */} +
+
+
+

+ IGNY8 ↔ WordPress Integration Debug +

+

+ Real-time monitoring of WordPress bridge plugin and content synchronization +

+
+ + {/* Debug Toggle */} +
+ + + {debugEnabled && pollingInterval && ( +
+ + Live +
+ )} +
+
+ + {/* Site Selector */} +
+ +
+ + {/* Debug Status Info */} + {debugEnabled ? ( +
+
+ +
+

WordPress Debug Mode Active

+

+ Real-time monitoring enabled for {activeSite?.name || 'selected site'}. + WordPress bridge plugin logs are being captured and will auto-disable after 24h. +

+
+
+
+ ) : ( +
+
+ +
+

WordPress Debug Mode Disabled

+

+ Enable debug mode above to start monitoring WordPress integration events and detailed sync logs. +

+
+
+
+ )} +
+ + {debugEnabled && activeSite ? ( + <> + {/* Integration Health Summary */} +
+
+

WordPress Bridge Health

+
+ + + +
+
+ + {integrationHealth ? ( +
+
+
+ API Connection + {integrationHealth.api_status === 'healthy' ? ( + + ) : ( + + )} +
+

{integrationHealth.api_message}

+
+ Last: {new Date(integrationHealth.last_api_check).toLocaleTimeString()} +
+
+ +
+
+ Plugin Status + {integrationHealth.plugin_active ? ( + + ) : ( + + )} +
+

+ Version: {integrationHealth.plugin_version || 'Unknown'} +

+
+ Debug: {integrationHealth.debug_mode ? 'Enabled' : 'Disabled'} +
+
+ +
+
+ Sync Status + {integrationHealth.sync_healthy ? ( + + ) : ( + + )} +
+

+ {integrationHealth.pending_syncs || 0} pending +

+
+ Last: {integrationHealth.last_sync ? + new Date(integrationHealth.last_sync).toLocaleTimeString() : 'Never'} +
+
+
+ ) : ( +
+ + Loading WordPress integration health... +
+ )} +
+ + {/* Live Action Logs */} +
+

Live WordPress Sync Events

+ + {syncEvents.length > 0 ? ( +
+ {syncEvents.slice().reverse().map((event, idx) => ( +
+
+
+
+ + {event.type} + + {event.action} +
+

{event.description}

+ {event.details && ( +
+ + View Details + +
+                              {typeof event.details === 'string' ? event.details : JSON.stringify(event.details, null, 2)}
+                            
+
+ )} +
+
+ {new Date(event.timestamp).toLocaleTimeString()} +
+
+
+ ))} +
+ ) : ( +
+ +

No WordPress sync events yet. Actions will appear here in real-time.

+

Content publishing, metadata sync, and webhook calls will be logged here.

+
+ )} +
+ + {/* Data Validation Matrix */} + {dataValidation.length > 0 && ( +
+

Data Sync Validation

+ +
+ + + + + + + + + + + {dataValidation.map((validation, idx) => ( + + + + + + + ))} + +
+ Field + + IGNY8 Value + + WordPress Value + + Status +
+ {validation.field_name} + + {validation.igny8_value || empty} + + {validation.wp_value || empty} + + {validation.matches ? ( + + ) : ( +
+ + {validation.error && ( + {validation.error} + )} +
+ )} +
+
+
+ )} + + ) : debugEnabled && !activeSite ? ( +
+
+ +

No Site Selected

+

+ Please select a site above to enable WordPress integration debug monitoring. +

+

+ Only sites with WordPress integrations will show debug data. +

+
+
+ ) : ( +
+
+ +

WordPress Debug Disabled

+

+ Enable the WordPress debug toggle above to start monitoring integration events. +

+

+ This will track content sync, plugin health, and API calls in real-time. +

+
+
+ )} +
+ ); +} \ No newline at end of file