Skip to content

Commit 2272bce

Browse files
committed
Add code
1 parent 5fd48de commit 2272bce

16 files changed

+8528
-1679
lines changed

package-lock.json

+6,362
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111
"dependencies": {
1212
"next": "12.2.4",
1313
"react": "18.2.0",
14-
"react-dom": "18.2.0"
14+
"react-dom": "18.2.0",
15+
"utf8": "^3.0.0"
1516
},
1617
"devDependencies": {
18+
"autoprefixer": "^10.4.8",
1719
"eslint": "8.21.0",
18-
"eslint-config-next": "12.2.4"
20+
"eslint-config-next": "12.2.4",
21+
"postcss": "^8.4.14",
22+
"tailwindcss": "^3.1.8"
1923
}
2024
}

pages/api/hello.js

-5
This file was deleted.

pages/index.js

-69
This file was deleted.

postcss.config.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}

src/assets/app.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;

src/components/Nav.js

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import Link from "next/link";
2+
import { useState, useEffect } from "react";
3+
4+
function NavLink({ children, href = "/" }) {
5+
return (
6+
<Link href={href}>
7+
<a className="inline-block p-3 font-bold text-decoration-none hover:underline">
8+
{children}
9+
</a>
10+
</Link>
11+
)
12+
}
13+
function toBeautyString(then) {
14+
15+
var nowdate = new Date();
16+
var thendate = then;
17+
18+
//finding the human-readable components of the date.
19+
20+
var y = nowdate.getFullYear() - thendate.getFullYear();
21+
var m = nowdate.getMonth() - thendate.getMonth();
22+
var d = nowdate.getDate() - thendate.getDate();
23+
var h = nowdate.getHours() - thendate.getHours();
24+
var mm = nowdate.getMinutes() - thendate.getMinutes();
25+
var s = nowdate.getSeconds() - thendate.getSeconds();
26+
27+
//back to second grade math, now we must now 'borrow'.
28+
29+
if (s < 0) {
30+
s += 60;
31+
mm--;
32+
}
33+
if (mm < 0) {
34+
mm += 60;
35+
h--;
36+
}
37+
if (h < 0) {
38+
h += 24;
39+
d--;
40+
}
41+
if (d < 0) {
42+
43+
//here's where we take into account variable month lengths.
44+
45+
var a = thendate.getMonth();
46+
var b;
47+
if (a <= 6) {
48+
if (a == 1) b = 28;
49+
else if (a % 2 == 0) b = 31;
50+
else b = 30;
51+
}
52+
else if (b % 2 == 0) b = 30;
53+
else b = 31;
54+
55+
d += b;
56+
m--;
57+
}
58+
if (m < 0) {
59+
m += 12;
60+
y--;
61+
}
62+
63+
return `
64+
${y > 0 ? `${y}y` : ""}
65+
${m > 0 ? `${m}M` : ""}
66+
${d > 0 ? `${d}d` : ""}
67+
${h > 0 ? `${h}h` : ""}
68+
${mm > 0 ? `${mm}m` : ""}
69+
${s > 0 ? `${s}s` : ""}
70+
ago
71+
`
72+
}
73+
function Updated() {
74+
const [date, setDate] = useState(new Date());
75+
const [relatime, setRelatime] = useState(null);
76+
77+
function update_time() {
78+
fetch("/api/updated")
79+
.then(res => res.text())
80+
.then(
81+
(text) => {
82+
setRelatime(
83+
toBeautyString(new Date(text))
84+
)
85+
}
86+
);
87+
}
88+
89+
useEffect(() => {
90+
update_time()
91+
setInterval(() => {
92+
update_time()
93+
}, 10000);
94+
}, []);
95+
96+
return (
97+
<div>
98+
{
99+
relatime ? (
100+
<>
101+
102+
Updated {relatime}
103+
104+
</>
105+
) : <>
106+
<div>
107+
loading...
108+
</div>
109+
</>
110+
}
111+
</div>
112+
)
113+
}
114+
115+
export default function Nav() {
116+
return (
117+
<nav className="flex items-center w-full justify-between px-4">
118+
<div>
119+
<ul>
120+
<NavLink href="/">Servers</NavLink>
121+
<NavLink href="/log">Last Log</NavLink>
122+
</ul>
123+
</div>
124+
<div>
125+
<Updated />
126+
</div>
127+
</nav>
128+
);
129+
}

src/components/Servers.js

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { useState, useEffect } from "react";
2+
import getUnicodeFlagIcon from 'country-flag-icons/unicode'
3+
import { ImSpinner8 } from 'react-icons/im'
4+
5+
function Th({ children }) {
6+
return (
7+
<th className="border border-slate-300">
8+
<div className="p-2">
9+
{children}
10+
</div>
11+
</th>
12+
)
13+
}
14+
function Td({ children }) {
15+
return (
16+
<td className="border border-slate-300">
17+
<div className="p-2">
18+
{children}
19+
</div>
20+
</td>
21+
)
22+
}
23+
24+
function ServerDisplay({ server }) {
25+
26+
const server_speed = server.speed_score;
27+
const server_speed_color = server_speed > 50 ? "bg-green-500" : server_speed > 30 ? "bg-orange-500" : "bg-red-500";
28+
29+
return (
30+
<div className="server p-3 w-1/4">
31+
<div className="shadow-md rounded-md overflow-hidden bg-white border">
32+
<div className="flex items-center justify-center bg-gray-100 p-3">
33+
<p>{getUnicodeFlagIcon(server.data.country)} {server.data.city}, {server.data.country}</p>
34+
</div>
35+
<div className="w-full bg-gray-200 h-1">
36+
<div className={`${server_speed_color} h-1`}
37+
style={{
38+
width: `${server.speed_score}%`
39+
}}>
40+
</div>
41+
</div>
42+
<div className="p-3">
43+
<table className="w-full border-collapse border border-slate-400 table-auto">
44+
<tbody>
45+
<tr>
46+
<Th>Protocol</Th>
47+
<Td><span className="uppercase">{server.proto}</span></Td>
48+
</tr>
49+
<tr>
50+
<Th>ISP</Th>
51+
<Td>
52+
{server.data.asn.name}
53+
</Td>
54+
</tr>
55+
</tbody>
56+
</table>
57+
<div className="text-center py-2">
58+
<input
59+
value={server.url}
60+
readOnly
61+
className="text-slate-400 w-full px-3 p-2 bg-gray-200 text-gray-700"
62+
/>
63+
</div>
64+
</div>
65+
</div>
66+
</div>
67+
)
68+
}
69+
70+
export default function Servers() {
71+
72+
const [servers, setServers] = useState([]);
73+
const [loading, setLoading] = useState(true);
74+
75+
useEffect(() => {
76+
fetch("/api/servers")
77+
.then(res => res.json())
78+
.then(
79+
json => {
80+
setServers(json)
81+
setLoading(false)
82+
}
83+
);
84+
}, []);
85+
86+
return (
87+
<div>
88+
<div className="flex flex-wrap items-center justify-start p-4">
89+
{
90+
loading &&
91+
<div className="w-full h-full flex items-center justify-center mt-12">
92+
<div className="spinner animate-spin h-5 w-5 flex items-center justify-center text-5xl">
93+
<ImSpinner8 />
94+
</div>
95+
</div>
96+
}
97+
{
98+
servers.map(server => {
99+
return <ServerDisplay key={server.url} server={server} />
100+
})
101+
}
102+
</div>
103+
</div>
104+
)
105+
}

pages/_app.js renamed to src/pages/_app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import '../styles/globals.css'
1+
import "../assets/app.css"
22

33
function MyApp({ Component, pageProps }) {
44
return <Component {...pageProps} />

src/pages/api/last_log.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
3+
export default async function handler(req, res) {
4+
const request = await fetch(`https://api.oproxy.ml/log`);
5+
const data = await request.text();
6+
res.statusCode = 200;
7+
res.send(data);
8+
}

src/pages/api/servers.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
3+
export default async function handler(req, res) {
4+
const request = await fetch(`https://api.oproxy.ml/servers`);
5+
const data = await request.json();
6+
res.statusCode = 200;
7+
res.json(data);
8+
}

src/pages/api/updated.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
3+
export default async function handler(req, res) {
4+
const request = await fetch(`https://api.oproxy.ml`);
5+
const data = await request.text();
6+
res.statusCode = 200;
7+
res.send(data);
8+
}

src/pages/index.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Nav from '../components/Nav';
2+
import Servers from '../components/Servers';
3+
export default function Index() {
4+
return (
5+
<div>
6+
<Nav />
7+
<Servers />
8+
</div>
9+
);
10+
}

0 commit comments

Comments
 (0)