feat: draft update ui

This commit is contained in:
2026-09-17 06:11:14 +08:00
parent de0666beb1
commit aa25af028e
9 changed files with 450 additions and 79 deletions
+91
View File
@@ -0,0 +1,91 @@
import { useEffect, useMemo } from "react";
import { useWAClient } from "./context";
import { useQuery } from "@tanstack/react-query";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
type Props = {
curDeviceId: string;
setDeviceId: (id: string) => void;
};
export default function DevicesSection({ curDeviceId, setDeviceId }: Props) {
const { client, isReady } = useWAClient();
const { data: devices } = useQuery({
queryKey: ["devices"],
queryFn: () => client.listDevices(),
enabled: isReady,
refetchInterval: 10_000,
});
useEffect(() => {
if (!curDeviceId && devices?.length && devices[0].id) {
setDeviceId(devices[0].id);
}
}, [curDeviceId, devices]);
const deviceList = useMemo(() => {
return devices?.map((i, idx) => {
const lastAlive = i.lastAlive || 0;
const isOnline = Date.now() - lastAlive <= 60_000;
return {
label: i.name || "Unknown",
value: i.id || String(idx),
lastAlive,
isOnline,
};
});
}, [devices]);
const curDevice = useMemo(() => {
return deviceList?.find((i) => i.value === curDeviceId);
}, [deviceList, curDeviceId]);
return (
<div className="border-t p-4">
<Select
items={deviceList}
value={curDeviceId}
onValueChange={(i) => setDeviceId(i || "")}
>
<SelectTrigger className="w-full justify-start">
<SelectValue placeholder="Select Device.." className="flex-none" />
{curDevice ? (
<span
className={
"inline-block size-3 rounded-full " +
(curDevice.isOnline ? "bg-green-500" : "bg-red-500")
}
/>
) : null}
<div className="flex-1" />
</SelectTrigger>
<SelectContent>
{deviceList?.map((i) => (
<SelectItem
key={i.value}
value={i.value}
className="cursor-pointer"
>
<div className="flex items-center gap-2">
<p>{i.label}</p>
<span
className={
"inline-block size-3 rounded-full " +
(i.isOnline ? "bg-green-500" : "bg-red-500")
}
/>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);
}