"use client"; import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { Monitor, Smartphone, Tablet } from "lucide-react"; import ConfirmDialog from "@/components/ConfirmDialog"; import { apiRevokeLoginDevice, type LoginDevice } from "@/lib/api"; import { formatDateTime } from "@/lib/format"; function DeviceIcon({ kind }: { kind: LoginDevice["device_kind"] }) { const props = { size: 20, strokeWidth: 1.75, "aria-hidden": true as const }; if (kind === "mobile") return ; if (kind === "tablet") return ; return ; } /** * 安全设置:仍有效的登录会话。 * 本机标「当前在线」;其它设备可剔除,对方需重新输入密码登录。 */ export default function LoginDevices({ devices: initial }: { devices: LoginDevice[] }) { const router = useRouter(); const [devices, setDevices] = useState(initial); const [target, setTarget] = useState(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { setDevices(initial); }, [initial]); async function confirmKick() { if (!target) return; setBusy(true); setError(""); try { const res = await apiRevokeLoginDevice(target.id); if (res.error) { setError(res.error); return; } setDevices((prev) => prev.filter((d) => d.id !== target.id)); setTarget(null); router.refresh(); } catch { setError("网络异常,请稍后重试"); } finally { setBusy(false); } } return ( 最近登录的设备 下列为仍有效的登录会话。若出现无法识别的设备,请立即剔除或修改密码 {devices.length === 0 ? ( 暂无登录记录 ) : ( {devices.map((d, i) => { const ip = d.ip || "未知 IP"; return ( {d.device_label} IP {ip} · {d.browser} {formatDateTime(d.created_at)} {d.current ? ( 当前在线 ) : ( { setError(""); setTarget(d); }} > 剔除 )} ); })} )} void confirmKick()} onCancel={() => { if (!busy) { setTarget(null); setError(""); } }} /> ); }
下列为仍有效的登录会话。若出现无法识别的设备,请立即剔除或修改密码
暂无登录记录
{d.device_label}
IP {ip} · {d.browser}
{formatDateTime(d.created_at)}
当前在线