Files
cunkebao_v3/Cunkebao/app/components/device-selection-dialog.tsx
2025-07-07 17:08:27 +08:00

155 lines
5.9 KiB
TypeScript

"use client"
import type React from "react"
import { useState, useEffect } from "react"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Checkbox } from "@/components/ui/checkbox"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Search, Smartphone } from "lucide-react"
import { Badge } from "@/components/ui/badge"
// 模拟设备数据
const mockDevices = [
{ id: "dev1", name: "iPhone 13", status: "online", lastActive: "2023-05-20T10:30:00Z" },
{ id: "dev2", name: "Xiaomi 12", status: "online", lastActive: "2023-05-20T09:15:00Z" },
{ id: "dev3", name: "Huawei P40", status: "offline", lastActive: "2023-05-19T18:45:00Z" },
{ id: "dev4", name: "OPPO Find X3", status: "online", lastActive: "2023-05-20T11:20:00Z" },
{ id: "dev5", name: "Samsung S21", status: "offline", lastActive: "2023-05-19T14:10:00Z" },
{ id: "dev6", name: "iPhone 12", status: "online", lastActive: "2023-05-20T08:30:00Z" },
{ id: "dev7", name: "Xiaomi 11", status: "online", lastActive: "2023-05-20T10:45:00Z" },
{ id: "dev8", name: "Huawei Mate 40", status: "offline", lastActive: "2023-05-18T16:20:00Z" },
]
interface DeviceSelectionDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
selectedDevices: string[]
onSelect: (selectedDevices: string[]) => void
}
export function DeviceSelectionDialog({ open, onOpenChange, selectedDevices, onSelect }: DeviceSelectionDialogProps) {
const [searchQuery, setSearchQuery] = useState("")
const [devices, setDevices] = useState<any[]>([])
const [loading, setLoading] = useState(true)
const [selected, setSelected] = useState<string[]>(selectedDevices)
useEffect(() => {
// 模拟API请求
const fetchData = async () => {
try {
// 实际项目中应从API获取数据
// const response = await fetch('/api/devices')
// const data = await response.json()
// setDevices(data)
// 使用模拟数据
setTimeout(() => {
setDevices(mockDevices)
setLoading(false)
}, 500)
} catch (error) {
console.error("获取设备失败:", error)
setLoading(false)
}
}
if (open) {
fetchData()
setSelected(selectedDevices)
}
}, [open, selectedDevices])
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchQuery(e.target.value)
}
const handleToggleSelect = (id: string) => {
setSelected((prev) => (prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]))
}
const handleSelectAll = () => {
if (selected.length === filteredDevices.length) {
setSelected([])
} else {
setSelected(filteredDevices.map((device) => device.id))
}
}
const handleConfirm = () => {
onSelect(selected)
onOpenChange(false)
}
const filteredDevices = devices.filter((device) => device.name.toLowerCase().includes(searchQuery.toLowerCase()))
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-md md:max-w-lg lg:max-w-xl">
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="relative mb-4">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500" />
<Input placeholder="搜索设备名称" className="pl-9" value={searchQuery} onChange={handleSearch} />
</div>
<div className="flex items-center justify-between mb-2">
<div className="text-sm text-gray-500">
{selected.length} / {filteredDevices.length}
</div>
<Button variant="ghost" size="sm" onClick={handleSelectAll}>
{selected.length === filteredDevices.length ? "取消全选" : "全选"}
</Button>
</div>
<ScrollArea className="h-[300px] rounded-md border p-2">
{loading ? (
<div className="flex items-center justify-center h-full">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>
</div>
) : filteredDevices.length === 0 ? (
<div className="flex items-center justify-center h-full text-gray-500"></div>
) : (
<div className="space-y-2">
{filteredDevices.map((device) => (
<div key={device.id} className="flex items-center space-x-3 p-2 rounded-md hover:bg-gray-100">
<Checkbox
id={`device-${device.id}`}
checked={selected.includes(device.id)}
onCheckedChange={() => handleToggleSelect(device.id)}
/>
<div className="flex-1">
<label htmlFor={`device-${device.id}`} className="flex items-center justify-between cursor-pointer">
<div className="flex items-center">
<Smartphone className="h-4 w-4 mr-2 text-gray-500" />
<div>
<div className="font-medium">{device.name}</div>
<div className="text-xs text-gray-500">ID: {device.id}</div>
</div>
</div>
<Badge variant={device.status === "online" ? "success" : "secondary"}>
{device.status === "online" ? "在线" : "离线"}
</Badge>
</label>
</div>
</div>
))}
</div>
)}
</ScrollArea>
<DialogFooter className="mt-4">
<Button variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button onClick={handleConfirm}></Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}