'use client' import { useState, useEffect } from 'react' import { GlobeAltIcon, ServerIcon, ShieldCheckIcon, ExclamationTriangleIcon, CheckCircleIcon, InformationCircleIcon } from '@heroicons/react/24/outline' interface NetworkInterface { name: string ip: string status: string speed?: string } interface NetworkConfig { primaryInterface: string primaryIP: string bzzzPort: number mcpPort: number webUIPort: number p2pPort: number autoFirewall: boolean allowedIPs: string[] dnsServers: string[] } interface NetworkConfigurationProps { systemInfo: any configData: any onComplete: (data: any) => void onBack?: () => void isCompleted: boolean } export default function NetworkConfiguration({ systemInfo, configData, onComplete, onBack, isCompleted }: NetworkConfigurationProps) { const [config, setConfig] = useState({ primaryInterface: '', primaryIP: '', bzzzPort: 8080, mcpPort: 3000, webUIPort: 8080, p2pPort: 7000, autoFirewall: true, allowedIPs: ['192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12'], dnsServers: ['8.8.8.8', '8.8.4.4'] }) const [errors, setErrors] = useState([]) const [portConflicts, setPortConflicts] = useState([]) // Initialize with system info and existing config useEffect(() => { if (systemInfo?.network) { setConfig(prev => ({ ...prev, primaryInterface: systemInfo.network.interfaces?.[0] || prev.primaryInterface, primaryIP: systemInfo.network.private_ips?.[0] || prev.primaryIP })) } if (configData.network) { setConfig(prev => ({ ...prev, ...configData.network })) } }, [systemInfo, configData]) // Validate configuration useEffect(() => { validateConfiguration() }, [config]) const validateConfiguration = () => { const newErrors: string[] = [] const conflicts: string[] = [] // Check for port conflicts const ports = [config.bzzzPort, config.mcpPort, config.webUIPort, config.p2pPort] const uniquePorts = new Set(ports) if (uniquePorts.size !== ports.length) { conflicts.push('Port numbers must be unique') } // Check port ranges ports.forEach((port, index) => { const portNames = ['BZZZ API', 'MCP Server', 'Web UI', 'P2P Network'] if (port < 1024) { newErrors.push(`${portNames[index]} port should be above 1024 to avoid requiring root privileges`) } if (port > 65535) { newErrors.push(`${portNames[index]} port must be below 65536`) } }) // Validate IP addresses in allowed IPs config.allowedIPs.forEach(ip => { if (ip && !isValidCIDR(ip)) { newErrors.push(`Invalid CIDR notation: ${ip}`) } }) // Validate DNS servers config.dnsServers.forEach(dns => { if (dns && !isValidIPAddress(dns)) { newErrors.push(`Invalid DNS server IP: ${dns}`) } }) setErrors(newErrors) setPortConflicts(conflicts) } const isValidCIDR = (cidr: string): boolean => { const regex = /^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$/ return regex.test(cidr) } const isValidIPAddress = (ip: string): boolean => { const regex = /^(\d{1,3}\.){3}\d{1,3}$/ if (!regex.test(ip)) return false return ip.split('.').every(part => parseInt(part) >= 0 && parseInt(part) <= 255) } const handlePortChange = (field: keyof NetworkConfig, value: string) => { const numValue = parseInt(value) || 0 setConfig(prev => ({ ...prev, [field]: numValue })) } const handleArrayChange = (field: 'allowedIPs' | 'dnsServers', index: number, value: string) => { setConfig(prev => ({ ...prev, [field]: prev[field].map((item, i) => i === index ? value : item) })) } const addArrayItem = (field: 'allowedIPs' | 'dnsServers') => { setConfig(prev => ({ ...prev, [field]: [...prev[field], ''] })) } const removeArrayItem = (field: 'allowedIPs' | 'dnsServers', index: number) => { setConfig(prev => ({ ...prev, [field]: prev[field].filter((_, i) => i !== index) })) } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (errors.length === 0 && portConflicts.length === 0) { onComplete({ network: config }) } } const isFormValid = errors.length === 0 && portConflicts.length === 0 return (
{/* Network Interface Selection */}

Network Interface

{systemInfo?.network?.interfaces && (
{config.primaryInterface && (
Primary IP: {systemInfo.network.private_ips?.[systemInfo.network.interfaces.indexOf(config.primaryInterface)] || 'Unknown'}
)}
)}
{/* Port Configuration */}

Port Configuration

handlePortChange('bzzzPort', e.target.value)} min="1024" max="65535" className="input-field" />

Main BZZZ HTTP API endpoint

handlePortChange('mcpPort', e.target.value)} min="1024" max="65535" className="input-field" />

Model Context Protocol server

handlePortChange('webUIPort', e.target.value)} min="1024" max="65535" className="input-field" />

Web interface port

handlePortChange('p2pPort', e.target.value)} min="1024" max="65535" className="input-field" />

Peer-to-peer communication

{portConflicts.length > 0 && (
Port Conflicts
{portConflicts.map((conflict, index) => (

{conflict}

))}
)}
{/* Security & Access Control */}

Security & Access Control

setConfig(prev => ({ ...prev, autoFirewall: e.target.checked }))} className="h-4 w-4 text-bzzz-primary focus:ring-bzzz-primary border-gray-300 rounded" />
{config.allowedIPs.map((ip, index) => (
handleArrayChange('allowedIPs', index, e.target.value)} placeholder="192.168.1.0/24" className="input-field flex-1" />
))}
{/* DNS Configuration */}

DNS Configuration

{config.dnsServers.map((dns, index) => (
handleArrayChange('dnsServers', index, e.target.value)} placeholder="8.8.8.8" className="input-field flex-1" />
))}
{/* Validation Errors */} {errors.length > 0 && (
Configuration Issues
{errors.map((error, index) => (

{error}

))}
)} {/* Configuration Summary */} {isFormValid && (
Configuration Summary

• Primary interface: {config.primaryInterface}

• BZZZ API will be available on port {config.bzzzPort}

• MCP server will run on port {config.mcpPort}

• Web UI will be accessible on port {config.webUIPort}

• P2P network will use port {config.p2pPort}

{config.autoFirewall &&

• Firewall rules will be configured automatically

}
)} {/* Action Buttons */}
{onBack && ( )}
) }