import { createFileRoute } from '@tanstack/react-router' import { route } from '@/constants/routes' import SettingsMenu from '@/containers/SettingsMenu' import HeaderPage from '@/containers/HeaderPage' import { Card, CardItem } from '@/containers/Card' import { Switch } from '@/components/ui/switch' import { Progress } from '@/components/ui/progress' import { useTranslation } from 'react-i18next' import { useHardware } from '@/hooks/useHardware' import type { GPU, HardwareData } from '@/hooks/useHardware' import { useEffect } from 'react' import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent, } from '@dnd-kit/core' import { SortableContext, verticalListSortingStrategy, useSortable, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { IconGripVertical } from '@tabler/icons-react' import { getHardwareInfo } from '@/services/hardware' // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Route = createFileRoute(route.settings.hardware as any)({ component: Hardware, }) // Format bytes to a human-readable format function formatMegaBytes(mb: number) { const tb = mb / (1024 * 1024) if (tb >= 1) { return `${tb.toFixed(2)} TB` } else { const gb = mb / 1024 return `${gb.toFixed(2)} GB` } } function SortableGPUItem({ gpu, index }: { gpu: GPU; index: number }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: gpu.id || index }) const { toggleGPUActivation } = useHardware() const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, position: 'relative' as const, zIndex: isDragging ? 1 : 0, } return (
{gpu.name}
} actions={
toggleGPUActivation(index)} />
} />
{formatMegaBytes(gpu.free_vram)} free of{' '} {formatMegaBytes(gpu.total_vram)} } /> {gpu.additional_information.driver_version} } /> {gpu.additional_information.compute_cap} } />
) } function Hardware() { const { t } = useTranslation() const { hardwareData, setHardwareData, updateCPUUsage, updateRAMAvailable, reorderGPUs, } = useHardware() useEffect(() => { getHardwareInfo().then((data) => setHardwareData(data as unknown as HardwareData) ) }, [setHardwareData]) // Set up DnD sensors const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor) ) // Handle drag end event const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event if (over && active.id !== over.id) { // Find the indices of the dragged item and the drop target const oldIndex = hardwareData.gpus.findIndex( (gpu) => gpu.id === active.id ) const newIndex = hardwareData.gpus.findIndex((gpu) => gpu.id === over.id) if (oldIndex !== -1 && newIndex !== -1) { reorderGPUs(oldIndex, newIndex) } } } useEffect(() => { const intervalId = setInterval(() => { getHardwareInfo().then((data) => { setHardwareData(data as unknown as HardwareData) updateCPUUsage(data.cpu.usage) updateRAMAvailable(data.ram.available) }) }, 5000) return () => clearInterval(intervalId) }, [setHardwareData, updateCPUUsage, updateRAMAvailable]) return (

{t('common.settings')}

{/* OS Information */} {hardwareData.os.name} } /> {hardwareData.os.version} } /> {/* CPU Information */} {hardwareData.cpu.model} } /> {hardwareData.cpu.arch} } /> {hardwareData.cpu.cores} } /> {hardwareData.cpu.instructions.join(', ').length > 0 && ( {hardwareData.cpu.instructions.join(', ')} } /> )} {hardwareData.cpu.usage.toFixed(2)}%
} /> {/* RAM Information */} {formatMegaBytes(hardwareData.ram.total)} } /> {formatMegaBytes(hardwareData.ram.available)} } /> {( ((hardwareData.ram.total - hardwareData.ram.available) / hardwareData.ram.total) * 100 ).toFixed(2)} %
} /> {/* GPU Information */} {hardwareData.gpus.length > 0 ? ( gpu.id)} strategy={verticalListSortingStrategy} > {hardwareData.gpus.map((gpu, index) => ( ))} ) : ( } /> )}
) }