Files
aken1023 2282eed9a1 增加ip 的白名單
總共7個IP地址,分佈在4個地點:
岡山:1個IP
汐止:2個IP
新竹:2個IP
璟茂:2個IP
2025-08-01 12:59:44 +08:00

210 lines
7.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Switch } from "@/components/ui/switch"
import { Shield, ShieldAlert, Globe, Save, RefreshCw } from "lucide-react"
import { toast } from "@/components/ui/use-toast"
interface IpInfo {
ip: string
isAllowed: boolean
enableIpWhitelist: boolean
allowedIps: string[]
timestamp: string
}
export default function IpWhitelistPage() {
const [ipInfo, setIpInfo] = useState<IpInfo | null>(null)
const [loading, setLoading] = useState(true)
const [saving, setSaving] = useState(false)
const [enableWhitelist, setEnableWhitelist] = useState(false)
const [allowedIps, setAllowedIps] = useState("")
useEffect(() => {
fetchIpInfo()
}, [])
const fetchIpInfo = async () => {
try {
setLoading(true)
const response = await fetch('/api/ip')
if (!response.ok) {
throw new Error('無法獲取IP信息')
}
const data = await response.json()
setIpInfo(data)
setEnableWhitelist(data.enableIpWhitelist)
setAllowedIps(data.allowedIps.join(', '))
} catch (error) {
console.error("無法獲取IP信息:", error)
toast({
title: "錯誤",
description: "無法獲取IP信息",
variant: "destructive",
})
} finally {
setLoading(false)
}
}
const handleSave = async () => {
try {
setSaving(true)
// 這裡應該調用API來保存設置
// 由於這是前端演示,我們只顯示成功消息
toast({
title: "成功",
description: "IP白名單設置已保存",
})
} catch (error) {
console.error("保存失敗:", error)
toast({
title: "錯誤",
description: "保存設置失敗",
variant: "destructive",
})
} finally {
setSaving(false)
}
}
if (loading) {
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-blue-900 to-indigo-900 flex items-center justify-center">
<div className="text-white text-center">
<RefreshCw className="w-8 h-8 animate-spin mx-auto mb-4" />
<p>...</p>
</div>
</div>
)
}
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-blue-900 to-indigo-900 p-4">
<div className="container mx-auto max-w-4xl">
<div className="mb-8">
<h1 className="text-3xl font-bold text-white mb-2">IP </h1>
<p className="text-blue-200">IP地址</p>
</div>
<div className="grid gap-6 md:grid-cols-2">
{/* 當前IP狀態 */}
<Card className="bg-slate-800/50 border-blue-800/30">
<CardHeader>
<CardTitle className="text-white flex items-center gap-2">
<Globe className="w-5 h-5" />
IP狀態
</CardTitle>
</CardHeader>
<CardContent>
{ipInfo && (
<div className="space-y-3">
<div className="flex items-center justify-between">
<span className="text-blue-200">IP地址:</span>
<span className="text-white font-mono">{ipInfo.ip}</span>
</div>
<div className="flex items-center justify-between">
<span className="text-blue-200">:</span>
<div className="flex items-center gap-2">
{ipInfo.enableIpWhitelist && !ipInfo.isAllowed ? (
<ShieldAlert className="w-4 h-4 text-red-400" />
) : (
<Shield className="w-4 h-4 text-green-400" />
)}
<span className={ipInfo.enableIpWhitelist && !ipInfo.isAllowed ? "text-red-400" : "text-green-400"}>
{ipInfo.enableIpWhitelist && !ipInfo.isAllowed ? "拒絕" : "允許"}
</span>
</div>
</div>
<div className="flex items-center justify-between">
<span className="text-blue-200">:</span>
<span className="text-white text-sm">
{new Date(ipInfo.timestamp).toLocaleString('zh-TW')}
</span>
</div>
</div>
)}
</CardContent>
</Card>
{/* 白名單設置 */}
<Card className="bg-slate-800/50 border-blue-800/30">
<CardHeader>
<CardTitle className="text-white flex items-center gap-2">
<Shield className="w-5 h-5" />
</CardTitle>
<CardDescription className="text-blue-200">
IP地址
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="enable-whitelist" className="text-blue-200">
IP白名單
</Label>
<Switch
id="enable-whitelist"
checked={enableWhitelist}
onCheckedChange={setEnableWhitelist}
/>
</div>
<div className="space-y-2">
<Label htmlFor="allowed-ips" className="text-blue-200">
IP地址
</Label>
<Input
id="allowed-ips"
value={allowedIps}
onChange={(e) => setAllowedIps(e.target.value)}
placeholder="192.168.1.0/24, 10.0.0.50, 172.16.0.0/16"
className="bg-slate-700 border-blue-600 text-white"
/>
<p className="text-xs text-blue-300">
IP (192.168.1.100)IP範圍 (192.168.1.0/24)IP用逗號分隔
</p>
</div>
<Button
onClick={handleSave}
disabled={saving}
className="w-full bg-blue-600 hover:bg-blue-700"
>
{saving ? (
<RefreshCw className="w-4 h-4 animate-spin mr-2" />
) : (
<Save className="w-4 h-4 mr-2" />
)}
</Button>
</CardContent>
</Card>
</div>
{/* 使用說明 */}
<Card className="mt-6 bg-slate-800/50 border-blue-800/30">
<CardHeader>
<CardTitle className="text-white">使</CardTitle>
</CardHeader>
<CardContent>
<div className="text-blue-200 space-y-2 text-sm">
<p> <strong>IP白名單</strong>IP才能訪問系統</p>
<p> <strong>IP格式支援</strong></p>
<ul className="ml-6 space-y-1">
<li> IP192.168.1.100</li>
<li> IP範圍192.168.1.0/24 (CIDR格式)</li>
<li> IP 192.168.1.100, 10.0.0.50</li>
</ul>
<p> <strong></strong></p>
</div>
</CardContent>
</Card>
</div>
</div>
)
}