mirror of
https://github.com/httpjamesm/AnonymousOverflow-hub.git
synced 2024-12-06 19:16:18 +01:00
feat: instance row component
This commit is contained in:
+4
@@ -0,0 +1,4 @@
|
||||
.operators {
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Instance } from "@/lib/interfaces/instance";
|
||||
import styles from "./InstanceRow.module.scss";
|
||||
|
||||
const InstanceRow = ({ instance }: { instance: Instance }) => {
|
||||
const domain = new URL(instance.url).hostname;
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<a href={instance.url} target="_blank" rel="noopener noreferrer">
|
||||
{domain}
|
||||
</a>
|
||||
</td>
|
||||
<td>{instance.regions.join(", ")}</td>
|
||||
<td>
|
||||
<div className={styles.operators}>
|
||||
{instance.operators.map((operator) => (
|
||||
<a
|
||||
href={operator}
|
||||
key={operator}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{new URL(operator).hostname}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
export default InstanceRow;
|
||||
@@ -1,5 +1,9 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import styles from "./InstancesTable.module.scss";
|
||||
import { Inter } from "next/font/google";
|
||||
import type { Instance } from "@/lib/interfaces/instance";
|
||||
import { fetchInstances } from "@/lib/instances";
|
||||
import InstanceRow from "./InstanceRow";
|
||||
|
||||
const inter = Inter({
|
||||
weight: ["400", "500", "600", "700"],
|
||||
@@ -7,6 +11,21 @@ const inter = Inter({
|
||||
});
|
||||
|
||||
const InstancesTable = () => {
|
||||
const [instances, setInstances] = useState<Instance[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
init();
|
||||
}, []);
|
||||
|
||||
const init = async () => {
|
||||
try {
|
||||
const instances = await fetchInstances();
|
||||
setInstances(instances);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={[styles.tableContainer, inter.className].join(" ")}>
|
||||
<table className={styles.table}>
|
||||
@@ -18,11 +37,9 @@ const InstancesTable = () => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Instance 1</td>
|
||||
<td>United States</td>
|
||||
<td>Admin 1</td>
|
||||
</tr>
|
||||
{instances.map((instance, i) => (
|
||||
<InstanceRow key={i} instance={instance} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Instance } from "./interfaces/instance";
|
||||
|
||||
export const fetchInstances = async () => {
|
||||
const instanceManifestUrl =
|
||||
process.env.NEXT_PUBLIC_INSTANCE_MANIFEST_URL ||
|
||||
"https://raw.githubusercontent.com/httpjamesm/AnonymousOverflow/main/instances.json";
|
||||
|
||||
const res = await fetch(instanceManifestUrl);
|
||||
|
||||
const data: Instance[] = await res.json();
|
||||
|
||||
return data;
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface Instance {
|
||||
url: string;
|
||||
regions: string[];
|
||||
operators: string[];
|
||||
}
|
||||
@@ -8,4 +8,12 @@ body,
|
||||
|
||||
body {
|
||||
background-color: #1B1F26;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #92adff;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
}
|
||||
Reference in New Issue
Block a user