Files
jh-monitor/src/app/dashboard/components/gatewayinfo.tsx
2025-09-15 16:29:49 +08:00

138 lines
4.4 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
interface GatewayInfo {
macaddr: string
inner_ip: string
setid: string
enable: number
}
export default function Gatewayinfo() {
const [data, setData] = useState<GatewayInfo[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState('')
const router = useRouter()
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
try {
setLoading(true)
setError('')
const response = await fetch('/api/stats?type=gateway_info')
if (!response.ok) {
throw new Error('获取网关信息失败')
}
const result = await response.json()
setData(result)
} catch (error) {
console.error('Failed to fetch gateway info:', error)
setError(error instanceof Error ? error.message : '获取网关信息失败')
} finally {
setLoading(false)
}
}
const getStatusText = (enable: number) => {
return enable === 1 ? '启用' : '禁用'
}
const getStatusClass = (enable: number) => {
return enable === 1
? 'bg-green-100 text-green-800'
: 'bg-red-100 text-red-800'
}
if (loading) {
return (
<div className="bg-white shadow rounded-lg p-6">
<h2 className="text-lg font-semibold mb-4"></h2>
<div className="text-center py-8">...</div>
</div>
)
}
if (error) {
return (
<div className="bg-white shadow rounded-lg p-6">
<h2 className="text-lg font-semibold mb-4"></h2>
<div className="text-center py-8 text-red-600">{error}</div>
</div>
)
}
return (
<div className="bg-white shadow rounded-lg p-6">
<h2 className="text-lg font-semibold mb-4"></h2>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<div className="bg-blue-50 p-4 rounded-lg">
<div className="text-2xl font-bold text-blue-600">{data.length}</div>
<div className="text-sm text-blue-800"></div>
</div>
<div className="bg-green-50 p-4 rounded-lg">
<div className="text-2xl font-bold text-green-600">
{data.filter(item => item.enable === 1).length}
</div>
<div className="text-sm text-green-800"></div>
</div>
<div className="bg-red-50 p-4 rounded-lg">
<div className="text-2xl font-bold text-red-600">
{data.filter(item => item.enable === 0).length}
</div>
<div className="text-sm text-red-800"></div>
</div>
<div className="bg-purple-50 p-4 rounded-lg">
<div className="text-2xl font-bold text-purple-600">
{new Set(data.map(item => item.setid)).size}
</div>
<div className="text-sm text-purple-800"></div>
</div>
</div>
<div className="overflow-x-auto">
<table className="min-w-full table-auto">
<thead>
<tr className="bg-gray-50">
<th className="px-4 py-2 text-left">MAC地址</th>
<th className="px-4 py-2 text-left">IP</th>
<th className="px-4 py-2 text-left"></th>
<th className="px-4 py-2 text-left"></th>
</tr>
</thead>
<tbody>
{data.map((item, index) => (
<tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className="px-4 py-2">
<button
onClick={() => {
router.push(`/dashboard?tab=gateway&mac=${item.macaddr}`);
}}
className="font-mono text-blue-600 hover:text-blue-800 hover:underline cursor-pointer"
>
{item.macaddr}
</button>
</td>
<td className="px-4 py-2">{item.inner_ip}</td>
<td className="px-4 py-2">{item.setid}</td>
<td className="px-4 py-2">
<span className={`px-2 py-1 rounded-full text-xs font-medium ${getStatusClass(item.enable)}`}>
{getStatusText(item.enable)}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)
}