Skip to content

Commit 32c2573

Browse files
authored
Merge pull request #294 from devvsakib/development
improved IPLOOKUP ui and API
2 parents fa1c243 + 01052dc commit 32c2573

File tree

1 file changed

+77
-34
lines changed

1 file changed

+77
-34
lines changed

src/components/DevAreaTools/IPLookup.jsx

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,28 @@ export default function IPLookup() {
44
const [ipAddress, setIpAddress] = useState('');
55
const [result, setResult] = useState(null);
66
const [loading, setLoading] = useState(false);
7+
const [error, setError] = useState(null);
78

89
const lookupIP = async (ip) => {
910
setLoading(true);
11+
setError(null);
1012
try {
11-
// Using ipapi.co - free, no API key
12-
const url = ip
13-
? `https://ipapi.co/${ip}/json/`
14-
: 'https://ipapi.co/json/';
15-
13+
const url = ip
14+
? `http://ip-api.com/json/${ip}?fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query`
15+
: `http://ip-api.com/json/?fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query`;
16+
1617
const response = await fetch(url);
1718
const data = await response.json();
18-
19-
setResult(data);
20-
} catch (error) {
21-
console.error('Error:', error);
22-
setResult({ error: 'Failed to lookup IP' });
19+
20+
if (data.status === 'fail') {
21+
setError(data.message);
22+
setResult(null);
23+
} else {
24+
setResult(data);
25+
}
26+
} catch (err) {
27+
setError('Failed to lookup IP');
28+
console.error('Error:', err);
2329
}
2430
setLoading(false);
2531
};
@@ -30,50 +36,87 @@ export default function IPLookup() {
3036
};
3137

3238
return (
33-
<div className="p-6">
34-
<h1 className="text-2xl font-bold mb-4">IP Address Lookup</h1>
35-
36-
<div className="flex gap-2 mb-4">
39+
<div className="max-w-4xl mx-auto p-6">
40+
<h1 className="text-3xl font-bold mb-6">IP Address Lookup</h1>
41+
42+
<div className="flex gap-2 mb-6">
3743
<input
3844
type="text"
3945
placeholder="Enter IP address (e.g., 8.8.8.8)"
4046
value={ipAddress}
4147
onChange={(e) => setIpAddress(e.target.value)}
42-
className="flex-1 px-4 py-2 border rounded"
48+
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
4349
/>
44-
<button
50+
<button
4551
onClick={() => lookupIP(ipAddress)}
4652
disabled={loading}
47-
className="px-6 py-2 bg-blue-500 text-white rounded"
53+
className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:bg-gray-400"
4854
>
49-
Lookup
55+
{loading ? 'Loading...' : 'Lookup'}
5056
</button>
51-
<button
57+
<button
5258
onClick={getMyIP}
5359
disabled={loading}
54-
className="px-6 py-2 bg-green-500 text-white rounded"
60+
className="px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400"
5561
>
5662
My IP
5763
</button>
5864
</div>
5965

60-
{loading && <p>Loading...</p>}
61-
62-
{result && !result.error && (
63-
<div className="bg-gray-100 p-4 rounded">
64-
<p><strong>IP:</strong> {result.ip}</p>
65-
<p><strong>City:</strong> {result.city}</p>
66-
<p><strong>Region:</strong> {result.region}</p>
67-
<p><strong>Country:</strong> {result.country_name}</p>
68-
<p><strong>Timezone:</strong> {result.timezone}</p>
69-
<p><strong>ISP:</strong> {result.org}</p>
70-
<p><strong>Latitude:</strong> {result.latitude}</p>
71-
<p><strong>Longitude:</strong> {result.longitude}</p>
66+
{error && (
67+
<div className="bg-slate-800 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
68+
{error}
7269
</div>
7370
)}
7471

75-
{result?.error && (
76-
<p className="text-red-500">{result.error}</p>
72+
{result && (
73+
<div className="bg-gray-500 border border-gray-700 rounded-lg shadow-sm overflow-hidden">
74+
<div className="bg-gray-50 px-6 py-4 border-b border-gray-200">
75+
<h2 className="text-xl font-semibold">IP Information</h2>
76+
</div>
77+
<div className="p-6 grid grid-cols-1 md:grid-cols-2 gap-4">
78+
<div className="flex flex-col">
79+
<span className="text-sm text-gray-500 mb-1">IP Address</span>
80+
<span className="font-mono font-semibold">{result.query}</span>
81+
</div>
82+
<div className="flex flex-col">
83+
<span className="text-sm text-gray-500 mb-1">Country</span>
84+
<span className="font-medium">{result.country} ({result.countryCode})</span>
85+
</div>
86+
<div className="flex flex-col">
87+
<span className="text-sm text-gray-500 mb-1">Region</span>
88+
<span className="font-medium">{result.regionName}</span>
89+
</div>
90+
<div className="flex flex-col">
91+
<span className="text-sm text-gray-500 mb-1">City</span>
92+
<span className="font-medium">{result.city}</span>
93+
</div>
94+
<div className="flex flex-col">
95+
<span className="text-sm text-gray-500 mb-1">ZIP Code</span>
96+
<span className="font-medium">{result.zip || 'N/A'}</span>
97+
</div>
98+
<div className="flex flex-col">
99+
<span className="text-sm text-gray-500 mb-1">Timezone</span>
100+
<span className="font-medium">{result.timezone}</span>
101+
</div>
102+
<div className="flex flex-col">
103+
<span className="text-sm text-gray-500 mb-1">ISP</span>
104+
<span className="font-medium">{result.isp}</span>
105+
</div>
106+
<div className="flex flex-col">
107+
<span className="text-sm text-gray-500 mb-1">Organization</span>
108+
<span className="font-medium">{result.org}</span>
109+
</div>
110+
<div className="flex flex-col">
111+
<span className="text-sm text-gray-500 mb-1">AS Number</span>
112+
<span className="font-mono text-sm">{result.as}</span>
113+
</div>
114+
<div className="flex flex-col">
115+
<span className="text-sm text-gray-500 mb-1">Coordinates</span>
116+
<span className="font-mono text-sm">{result.lat}, {result.lon}</span>
117+
</div>
118+
</div>
119+
</div>
77120
)}
78121
</div>
79122
);

0 commit comments

Comments
 (0)