80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
import React, { useMemo } from 'react';
|
|
import { NetworkDevice, NetworkDeviceType } from '../../types';
|
|
import NetworkDeviceCard from './NetworkDeviceCard';
|
|
|
|
const deviceConfig: { [key in NetworkDeviceType]: { icon: string; color: string } } = {
|
|
[NetworkDeviceType.ROUTER]: { icon: 'fa-route', color: 'text-blue-500' },
|
|
[NetworkDeviceType.SWITCH]: { icon: 'fa-network-wired', color: 'text-green-600' },
|
|
[NetworkDeviceType.ACCESS_POINT]: { icon: 'fa-wifi', color: 'text-purple-500' },
|
|
};
|
|
|
|
interface NetworkDeviceDashboardProps {
|
|
devices: NetworkDevice[];
|
|
getLocationName: (device: NetworkDevice) => string;
|
|
}
|
|
|
|
const NetworkDeviceDashboard: React.FC<NetworkDeviceDashboardProps> = ({
|
|
devices,
|
|
getLocationName,
|
|
}) => {
|
|
const groupedDevices = useMemo(() => {
|
|
return devices.reduce(
|
|
(acc, device) => {
|
|
const type = device.type;
|
|
if (!acc[type]) {
|
|
acc[type] = [];
|
|
}
|
|
acc[type].push(device);
|
|
return acc;
|
|
},
|
|
{} as Record<NetworkDeviceType, NetworkDevice[]>
|
|
);
|
|
}, [devices]);
|
|
|
|
const typeOrder = Object.values(NetworkDeviceType);
|
|
|
|
const sortedGroupedDevices = useMemo(() => {
|
|
return Object.entries(groupedDevices).sort(([typeA], [typeB]) => {
|
|
return (
|
|
typeOrder.indexOf(typeA as NetworkDeviceType) -
|
|
typeOrder.indexOf(typeB as NetworkDeviceType)
|
|
);
|
|
});
|
|
}, [groupedDevices, typeOrder]);
|
|
|
|
return (
|
|
<div className="bg-white p-6 rounded-xl shadow-sm">
|
|
<h2 className="text-xl font-bold mb-4">Daftar Perangkat Jaringan</h2>
|
|
<div className="space-y-8">
|
|
{sortedGroupedDevices.map(([type, deviceList]) => {
|
|
const config = deviceConfig[type as NetworkDeviceType];
|
|
return (
|
|
<section key={type} aria-labelledby={`net-type-header-${type}`}>
|
|
<div className="flex items-center gap-4 mb-4 pb-2 border-b border-gray-200">
|
|
<i className={`fa-solid ${config.icon} text-2xl ${config.color}`}></i>
|
|
<h3 id={`net-type-header-${type}`} className="text-lg font-bold text-gray-800">
|
|
{type}
|
|
</h3>
|
|
<span className="text-gray-500 font-semibold bg-gray-100 px-3 py-1 rounded-full text-sm">
|
|
{deviceList.length} Perangkat
|
|
</span>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
{deviceList.map((device) => (
|
|
<NetworkDeviceCard
|
|
key={device.id}
|
|
device={device}
|
|
locationName={getLocationName(device)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default NetworkDeviceDashboard;
|