import React, { useState, useEffect } from 'react' import { Plus, RefreshCw, Search, Filter } from 'lucide-react' import { Button } from '../ui/button' import { Input } from '../ui/input' import { LoadingSpinner } from '../ui/loading-spinner' import { DeviceCard } from './device-card' import { DeviceRegistrationWizard } from './device-registration-wizard' import { useDeviceRegistration } from '../../contexts/device-registration-context' import { DeviceDto, DeviceStatus } from '../../types/device' interface DeviceManagementDashboardProps { className?: string } export function DeviceManagementDashboard({ className }: DeviceManagementDashboardProps) { const { state, refreshDevices, updateDevice, deleteDevice } = useDeviceRegistration() const [showRegistrationWizard, setShowRegistrationWizard] = useState(false) const [searchQuery, setSearchQuery] = useState('') const [statusFilter, setStatusFilter] = useState('all') const [isRefreshing, setIsRefreshing] = useState(false) // Load devices on mount useEffect(() => { refreshDevices() }, [refreshDevices]) const handleRefresh = async () => { setIsRefreshing(true) try { await refreshDevices() } finally { setIsRefreshing(false) } } const handleDeleteDevice = async (device: DeviceDto) => { if (window.confirm(`确定要删除设备 "${device.deviceName || '此设备'}" 吗?此操作无法撤销。`)) { await deleteDevice(device.id) } } const handleEditDevice = async (device: DeviceDto) => { const newName = window.prompt('请输入新的设备名称:', device.deviceName || '') if (newName && newName.trim() !== device.deviceName) { await updateDevice(device.id, { deviceName: newName.trim() }) } } const handleConfigureDevice = (device: DeviceDto) => { // TODO: Implement device configuration dialog console.log('Configure device:', device) } // Filter devices based on search query and status const filteredDevices = state.registeredDevices.filter(device => { const matchesSearch = !searchQuery || (device.deviceName?.toLowerCase().includes(searchQuery.toLowerCase()) || device.hardwareId.toLowerCase().includes(searchQuery.toLowerCase())) const matchesStatus = statusFilter === 'all' || device.status === statusFilter return matchesSearch && matchesStatus }) const getDeviceStats = () => { const total = state.registeredDevices.length const online = state.registeredDevices.filter(d => d.status === DeviceStatus.ONLINE || d.status === DeviceStatus.ACTIVE ).length const offline = state.registeredDevices.filter(d => d.status === DeviceStatus.OFFLINE || d.status === DeviceStatus.INACTIVE ).length const maintenance = state.registeredDevices.filter(d => d.status === DeviceStatus.MAINTENANCE ).length return { total, online, offline, maintenance } } const stats = getDeviceStats() return (
{/* Header */}

设备管理

管理您的流星监测设备

{/* Stats Cards */}
{stats.total}
设备总数
{stats.online}
在线
{stats.offline}
离线
{stats.maintenance}
维护中
{/* 筛选和搜索 - 参考天气页面样式 */}
setSearchQuery(e.target.value)} />
设备状态:
{/* WebSocket Connection Status */} {!state.wsConnected && (
实时更新不可用,设备状态可能不是最新的。
)} {/* Device Grid */} {state.isLoading && filteredDevices.length === 0 ? (
加载设备中...
) : filteredDevices.length === 0 ? (
{searchQuery || statusFilter !== 'all' ? '没有符合筛选条件的设备' : '尚未注册任何设备'}
{!searchQuery && statusFilter === 'all' && (

注册您的第一台流星监测设备,开始使用。

)}
) : (
{filteredDevices.map((device) => ( ))}
)} {/* Error Display */} {state.error && (

错误

{state.error}

)} {/* Registration Wizard */}
) }