wulf-pulse/components/configuration-items/auvik-tab.tsx

246 lines
8.8 KiB
TypeScript
Raw Normal View History

import { AuvikDevice } from '@/lib/types/auvik';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Label } from '@/components/ui/label';
import { Network, Info, Wifi, XCircle, AlertCircle } from 'lucide-react';
interface AuvikTabProps {
device?: AuvikDevice;
}
export function AuvikTab({ device }: AuvikTabProps) {
if (!device) {
return (
<div className="flex flex-col items-center justify-center py-12 text-center">
<Network className="w-16 h-16 text-muted-foreground mb-4" />
<h3 className="text-lg font-semibold mb-2">No Auvik data available</h3>
<p className="text-sm text-muted-foreground max-w-md">
This device is not monitored by Auvik or could not be matched to an Auvik device.
</p>
</div>
);
}
const formatDate = (dateString?: string) => {
if (!dateString) return 'N/A';
return new Date(dateString).toLocaleString();
};
const getStatusBadge = () => {
switch (device.onlineStatus) {
case 'online':
return (
<Badge className="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100">
<Wifi className="w-3 h-3 mr-1" />
Online
</Badge>
);
case 'offline':
return (
<Badge variant="secondary">
<XCircle className="w-3 h-3 mr-1" />
Offline
</Badge>
);
default:
return (
<Badge variant="outline">
<AlertCircle className="w-3 h-3 mr-1" />
Unknown
</Badge>
);
}
};
return (
<div className="space-y-6">
{/* Status Header */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Network className="w-5 h-5 text-muted-foreground" />
<h3 className="text-lg font-semibold">{device.deviceName}</h3>
</div>
{getStatusBadge()}
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Basic Information */}
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Info className="w-4 h-4" />
Basic Information
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div>
<Label className="text-xs text-muted-foreground">Device Name</Label>
<p className="text-sm font-medium">{device.deviceName || 'N/A'}</p>
</div>
<div>
<Label className="text-xs text-muted-foreground">Device Type</Label>
<p className="text-sm font-medium capitalize">{device.deviceType || 'N/A'}</p>
</div>
<div>
<Label className="text-xs text-muted-foreground">Serial Number</Label>
<p className="text-sm font-medium font-mono">{device.serialNumber || 'N/A'}</p>
</div>
<div>
<Label className="text-xs text-muted-foreground">Manufacturer</Label>
<p className="text-sm font-medium">{device.manufacturer || device.vendorName || 'N/A'}</p>
</div>
<div>
<Label className="text-xs text-muted-foreground">Model</Label>
<p className="text-sm font-medium">{device.model || device.makeModel || 'N/A'}</p>
</div>
</CardContent>
</Card>
{/* Network Information */}
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Network className="w-4 h-4" />
Network Information
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div>
<Label className="text-xs text-muted-foreground">IP Addresses</Label>
{device.ipAddresses && device.ipAddresses.length > 0 ? (
<div className="flex flex-wrap gap-1 mt-1">
{device.ipAddresses.map((ip, index) => (
<Badge key={index} variant="outline" className="font-mono text-xs">
{ip}
</Badge>
))}
</div>
) : (
<p className="text-sm text-muted-foreground">N/A</p>
)}
</div>
<div>
<Label className="text-xs text-muted-foreground">MAC Addresses</Label>
{device.macAddresses && device.macAddresses.length > 0 ? (
<div className="flex flex-wrap gap-1 mt-1">
{device.macAddresses.map((mac, index) => (
<Badge key={index} variant="outline" className="font-mono text-xs">
{mac}
</Badge>
))}
</div>
) : (
<p className="text-sm text-muted-foreground">N/A</p>
)}
</div>
<div>
<Label className="text-xs text-muted-foreground">Tenant</Label>
<p className="text-sm font-medium">{device.tenantName || 'N/A'}</p>
</div>
</CardContent>
</Card>
{/* Status Information */}
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Wifi className="w-4 h-4" />
Status Information
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div>
<Label className="text-xs text-muted-foreground">Online Status</Label>
<div className="mt-1">{getStatusBadge()}</div>
</div>
<div>
<Label className="text-xs text-muted-foreground">Last Seen</Label>
<p className="text-sm font-medium">{formatDate(device.lastSeenTime)}</p>
</div>
</CardContent>
</Card>
{/* Firmware Information */}
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Info className="w-4 h-4" />
Firmware Information
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div>
<Label className="text-xs text-muted-foreground">Firmware Version</Label>
<p className="text-sm font-medium font-mono">
{device.firmwareVersion || 'N/A'}
</p>
</div>
<div>
<Label className="text-xs text-muted-foreground">Software Version</Label>
<p className="text-sm font-medium font-mono">
{device.softwareVersion || 'N/A'}
</p>
</div>
</CardContent>
</Card>
</div>
{/* Description */}
{device.description && (
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium">Description</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">{device.description}</p>
</CardContent>
</Card>
)}
{/* Network Interfaces */}
{device.networkInterfaces && device.networkInterfaces.length > 0 && (
<Card>
<CardHeader>
<CardTitle className="text-sm font-medium flex items-center gap-2">
<Network className="w-4 h-4" />
Network Interfaces
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
{device.networkInterfaces.map((iface, index) => (
<div
key={index}
className="flex items-center justify-between p-2 border rounded-md"
>
<div className="flex-1">
<p className="text-sm font-medium">{iface.interfaceName}</p>
{iface.macAddress && (
<p className="text-xs text-muted-foreground font-mono">
{iface.macAddress}
</p>
)}
</div>
<div className="flex items-center gap-2">
{iface.ipAddress && (
<Badge variant="outline" className="font-mono text-xs">
{iface.ipAddress}
</Badge>
)}
<Badge
variant={iface.status === 'up' ? 'default' : 'secondary'}
className="text-xs"
>
{iface.status}
</Badge>
</div>
</div>
))}
</div>
</CardContent>
</Card>
)}
</div>
);
}