import React, { useRef, useEffect, useState } from 'react'; import { AlertTriangle, Loader2, ScanSearch, ServerCrash } from 'lucide-react'; import { type Service } from '../types'; interface ScanInfoModalProps { onClose: () => void; onScanComplete: (services: Omit[]) => void; } type ScanStatus = 'idle' | 'scanning' | 'error'; const ScanInfoModal: React.FC = ({ onClose, onScanComplete }) => { const modalRef = useRef(null); const [networkAddress, setNetworkAddress] = useState('192.168.1.0/24'); const [scanStatus, setScanStatus] = useState('idle'); const [errorMessage, setErrorMessage] = useState(''); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (modalRef.current && !modalRef.current.contains(event.target as Node)) { onClose(); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [onClose]); const handleStartScan = async (e: React.FormEvent) => { e.preventDefault(); setScanStatus('scanning'); setErrorMessage(''); try { const response = await fetch('http://localhost:3001/api/scan', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ network: networkAddress }), }); if (!response.ok) { // Try to parse a specific error message from the backend, otherwise show a generic one. const errorData = await response.json().catch(() => ({ error: `Request failed with status: ${response.status}` })); setErrorMessage(errorData.error || 'An unknown error occurred during the scan.'); setScanStatus('error'); return; } const discoveredServices = await response.json(); onScanComplete(discoveredServices); onClose(); } catch (err) { // This catch block handles network errors (e.g., server not running) console.error(err); setErrorMessage('Scan failed. Is the backend server running? Make sure you have started the server in the `server` directory and that nmap is installed. See README.md for details.'); setScanStatus('error'); } }; const renderContent = () => { switch (scanStatus) { case 'scanning': return (

Scanning Network

Discovering services on {networkAddress}...

This may take a few minutes depending on your network.

); case 'error': return (

Scan Failed

Error Details {errorMessage}
); case 'idle': default: return (

Scan Your Local Network

Enter your local network address range below to automatically discover web services.

setNetworkAddress(e.target.value)} className="mt-1 block w-full bg-gray-900 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-white focus:outline-none focus:ring-teal-500 focus:border-teal-500 sm:text-sm font-mono" placeholder="e.g., 192.168.1.0/24" required />
); } }; return (
{renderContent()}
); }; export default ScanInfoModal;