// src/components/DeviceListSidebar.tsx 'use client'; import React from 'react'; import { List, ListItemButton, ListItemIcon, ListItemText, Typography, Box,TextField } from '@mui/material'; import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord'; import { parseISO, formatDistanceToNowStrict } from 'date-fns'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import { DetailedDevice } from '@/types/devices'; import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; interface DeviceListSidebarProps { devices: DetailedDevice[]; selectedDevice: number | null; onSelect: (deviceId: number) => void; open: boolean; onMouseEnter?: () => void; onMouseLeave?: () => void; pinned?: boolean; onTogglePin?: () => void; } const ONLINE_THRESHOLD_MINUTES = 1440; function getStatusColor(lastCheckedIn: string) { const lastSeen = parseISO(lastCheckedIn); const minutesAgo = (Date.now() - lastSeen.getTime()) / 1000 / 60; return minutesAgo < ONLINE_THRESHOLD_MINUTES ? 'green' : 'grey'; } function formatRelativeTime(lastCheckedIn: string) { try { return formatDistanceToNowStrict(parseISO(lastCheckedIn), { addSuffix: true }); } catch { return 'Unknown'; } } const DeviceListSidebar: React.FC = ({ devices, selectedDevice, onSelect, open, onMouseEnter, onMouseLeave, pinned, onTogglePin, }) => { const [sortAsc, setSortAsc] = React.useState(true); const [searchQuery, setSearchQuery] = React.useState(''); return ( setSearchQuery(e.target.value)} variant="outlined" sx={{ mt: 1 }} /> {devices.length === 0 && ( No devices received (length: 0) )} {/* Header */} Select a Device setSortAsc((prev) => !prev)} sx={{ ml: 'auto' }} // Pushes it to the right > {sortAsc ? : } {open && onTogglePin && ( { e.stopPropagation(); onTogglePin?.(); }} sx={(theme) => ({ position: 'absolute', right: -10, top: 'calc(50% - 64px)', // offsets for AppBar height transform: 'translateY(-50%)', backgroundColor: 'background.paper', border: '1px solid', borderColor: 'divider', borderRadius: '0 4px 4px 0', zIndex: theme.zIndex.drawer + 1, transition: 'background-color 0.2s ease-in-out', '&:hover': { backgroundColor: theme.palette.action.hover, }, })} > {pinned ? : } )} {/* Device list */} {[...devices] .sort((a, b) => sortAsc ? a.hostname.localeCompare(b.hostname) : b.hostname.localeCompare(a.hostname) ) .filter((device) => device.hostname.toLowerCase().includes(searchQuery.toLowerCase()) ) .map((device) => ( onSelect(device.deviceId)} sx={{ alignItems: 'flex-start', minHeight: 56, px: open ? 2 : 1.5, py: 1, }} > {/* Hostname: Always visible */} {device.hostname} {/* Last seen: Only visible when expanded */} 🕒 {formatRelativeTime(device.lastCheckedIn)} ))} ); }; export default DeviceListSidebar;