import React, { useState, useEffect, useCallback } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/index'; import { Button } from '@/components/ui/index'; import { Badge } from '@/components/ui/index'; import { RefreshCw, Network, Plus, Edit, Trash2 } from 'lucide-react'; import { listNetworkInterfaces, listProxmoxClusters, NetworkInterface } from '@/lib/proxmoxClient'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/index'; import { Input } from '@/components/ui/index'; import { Label } from '@/components/ui/index'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/index'; import { toast } from 'sonner'; export function ProxmoxNetworkPage() { const [interfaces, setInterfaces] = useState([]); const [clusterId, setClusterId] = useState(''); const [nodeId] = useState('localhost'); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [showAddDialog, setShowAddDialog] = useState(false); const [editingInterface] = useState(null); // Form state const [ifaceName, setIfaceName] = useState(''); const [ifaceType, setIfaceType] = useState('eth'); const [address, setAddress] = useState(''); const [netmask, setNetmask] = useState(''); const [gateway, setGateway] = useState(''); const [active, setActive] = useState(true); const loadInterfaces = useCallback(async (cId: string, nId: string) => { if (!cId) return; setLoading(true); setError(null); try { const ifaces = await listNetworkInterfaces(cId, nId); setInterfaces(ifaces); } catch (e) { setError(String(e)); } finally { setLoading(false); } }, []); useEffect(() => { listProxmoxClusters() .then((cls) => { if (cls.length > 0) { setClusterId(cls[0].id); void loadInterfaces(cls[0].id, nodeId); } }) .catch(console.error); }, [loadInterfaces, nodeId]); const NOT_IMPLEMENTED_MSG = 'Network interface management requires additional backend implementation (POST/PUT/DELETE nodes/{node}/network) and is not yet available.'; const handleAddInterface = () => { toast.warning(NOT_IMPLEMENTED_MSG); }; const handleEditInterface = (_iface: NetworkInterface) => { toast.warning(NOT_IMPLEMENTED_MSG); }; const handleSubmit = async () => { toast.warning(NOT_IMPLEMENTED_MSG); setShowAddDialog(false); }; const handleDeleteInterface = async (_iface: NetworkInterface) => { toast.warning(NOT_IMPLEMENTED_MSG); }; return (

Network

Network interfaces and bridges

{error && (
{error}
)} Network Interfaces {loading ? (
Loading...
) : interfaces.length === 0 ? (
{clusterId ? 'No network interfaces found.' : 'No cluster configured.'}
) : (
{interfaces.map((iface, i) => (
{iface.iface} {iface.type} {iface.active ? 'Active' : 'Inactive'} {iface.autostart && ( Autostart )}
{(iface.address || iface.gateway) && (
{iface.address && ( {iface.address} {iface.netmask ? `/${iface.netmask}` : ''} )} {iface.gateway && ( gw {iface.gateway} )}
)} {iface.comments && (
{iface.comments}
)}
))}
)}
{editingInterface ? 'Edit Network Interface' : 'Add Network Interface'}
setIfaceName(e.target.value)} placeholder="eth0" />
setAddress(e.target.value)} placeholder="192.168.1.100" />
setNetmask(e.target.value)} placeholder="24" />
setGateway(e.target.value)} placeholder="192.168.1.1" />
setActive(e.target.checked)} className="rounded" />
); }