import React, { useState, useEffect } from 'react'; import api from '../services/api'; import { format } from 'date-fns'; import { BugAntIcon, ExclamationTriangleIcon, InformationCircleIcon, EyeIcon, TrashIcon, DocumentTextIcon, XMarkIcon } from '@heroicons/react/24/outline'; const Debug = () => { const [debugData, setDebugData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [pagination, setPagination] = useState({}); const [debugInfo, setDebugInfo] = useState({}); const [showPayloadModal, setShowPayloadModal] = useState(false); const [selectedPayload, setSelectedPayload] = useState(null); const [payloadLoading, setPayloadLoading] = useState(false); const [filters, setFilters] = useState({ drone_type: '', device_id: '', page: 1, limit: 50 }); useEffect(() => { fetchDebugData(); }, [filters]); const fetchDebugData = async () => { try { setLoading(true); const params = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value) params.append(key, value); }); const response = await api.get(`/detections/debug?${params}`); if (response.data.success) { setDebugData(response.data.data); setPagination(response.data.pagination); setDebugInfo(response.data.debug_info); } else { setError(response.data.message || 'Failed to fetch debug data'); } } catch (err) { console.error('Error fetching debug data:', err); setError(err.response?.data?.message || 'Failed to fetch debug data'); } finally { setLoading(false); } }; const handleFilterChange = (key, value) => { setFilters(prev => ({ ...prev, [key]: value, page: 1 // Reset to first page when filtering })); }; const handlePageChange = (newPage) => { setFilters(prev => ({ ...prev, page: newPage })); }; const fetchRawPayload = async (detectionId) => { try { setPayloadLoading(true); const response = await api.get(`/debug/detection-payloads?limit=1&detection_id=${detectionId}`); if (response.data.success && response.data.data.length > 0) { const detection = response.data.data[0]; setSelectedPayload({ id: detection.id, timestamp: detection.server_timestamp, deviceId: detection.device_id, rawPayload: detection.raw_payload, processedData: { drone_id: detection.drone_id, drone_type: detection.drone_type, rssi: detection.rssi, freq: detection.freq, geo_lat: detection.geo_lat, geo_lon: detection.geo_lon, device_timestamp: detection.device_timestamp, confidence_level: detection.confidence_level, signal_duration: detection.signal_duration } }); setShowPayloadModal(true); } else { console.error('No payload data found for detection:', detectionId); alert('No raw payload data found for this detection'); } } catch (err) { console.error('Error fetching payload:', err); alert('Failed to fetch payload data'); } finally { setPayloadLoading(false); } }; const closePayloadModal = () => { setShowPayloadModal(false); setSelectedPayload(null); }; const getDroneTypeColor = (droneType) => { if (droneType === 0) return 'bg-gray-100 text-gray-800'; return 'bg-blue-100 text-blue-800'; }; const getThreatLevelColor = (threatLevel) => { switch (threatLevel?.toLowerCase()) { case 'critical': return 'bg-red-100 text-red-800'; case 'high': return 'bg-orange-100 text-orange-800'; case 'medium': return 'bg-yellow-100 text-yellow-800'; case 'low': return 'bg-green-100 text-green-800'; default: return 'bg-gray-100 text-gray-800'; } }; if (loading) { return (
); } if (error) { return (

Error

{error}
); } return (
{/* Header */}

Debug Console

Admin-only access to all detection data including drone type 0 (None)

{/* Debug Info */} {debugInfo && (

Debug Information

{debugInfo.message}

Total None detections: {debugInfo.total_none_detections}

)} {/* Filters */}

Filters

handleFilterChange('device_id', e.target.value)} className="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-primary-500 focus:border-primary-500" placeholder="Filter by device ID" />
{/* Debug Data Table */}

Debug Detections ({pagination.total || 0})

{debugData.length === 0 ? (

No debug data

No detections found matching the current filters.

) : ( <>
{debugData.map((detection) => ( ))}
ID / Time Device Drone Type RSSI / Freq Threat Level Debug Actions
#{detection.id}
{format(new Date(detection.server_timestamp), 'MMM dd, HH:mm:ss')}
{detection.device?.name || `Device ${detection.device_id}`}
ID: {detection.device_id}
{detection.drone_type_info?.name || `Type ${detection.drone_type}`}
ID: {detection.drone_type}
{detection.rssi} dBm
{detection.freq} MHz
{detection.threat_level ? ( {detection.threat_level} ) : ( N/A )} {detection.is_debug_data && ( Debug Data )}
{/* Pagination */} {pagination.pages > 1 && (

Showing {((pagination.page - 1) * pagination.limit) + 1} to{' '} {Math.min(pagination.page * pagination.limit, pagination.total)} {' '} of {pagination.total} results

)} )}
{/* Raw Payload Modal */} {showPayloadModal && selectedPayload && (
{/* Modal Header */}

Raw Payload Data

{/* Detection Info */}

Detection Information

Detection ID: {selectedPayload.id}
Device ID: {selectedPayload.deviceId}
Server Timestamp: {format(new Date(selectedPayload.timestamp), 'yyyy-MM-dd HH:mm:ss')}
Drone Type: {selectedPayload.processedData.drone_type}
{/* Processed Data */}

Processed Data

                    {JSON.stringify(selectedPayload.processedData, null, 2)}
                  
{/* Raw Payload */}

Raw Payload from Detector

{selectedPayload.rawPayload ? (
                      {JSON.stringify(selectedPayload.rawPayload, null, 2)}
                    
) : (

⚠️ No raw payload data available. This might occur if:

  • STORE_RAW_PAYLOAD environment variable is disabled
  • This detection was created before raw payload storage was enabled
  • The detection was processed without storing the original payload
)}
{/* Modal Footer */}
)}
); }; export default Debug;