<RouterLink to="/builders" class="navbar-item">
{{ $t("Builders") }}
</RouterLink>
+
+ <RouterLink to="/mirrors" class="navbar-item">
+ {{ $t("Mirrors") }}
+ </RouterLink>
</div>
<div class="navbar-end">
--- /dev/null
+import type { Mirror } from "@/types/Mirror";
+
+export async function fetchMirrors(): Promise<Mirror[]> {
+ // Fetch all mirrors
+ const response = await fetch("/api/v1/mirrors");
+ if (!response.ok)
+ throw new Error("Failed to fetch mirrors");
+
+ return response.json();
+}
import HomeView from '../views/HomeView.vue'
import LoginView from "../views/LoginView.vue"
import BuildersView from "../views/BuildersView.vue"
+import MirrorsView from "../views/MirrorsView.vue"
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
name: "builders",
component: BuildersView,
},
+
+ // Mirrors
+ {
+ path: "/mirrors",
+ name: "mirrors",
+ component: MirrorsView,
+ },
],
})
--- /dev/null
+/*
+ Defines a Mirror
+*/
+export interface Mirror {
+ // Hostanme
+ hostname: string;
+
+ // Path
+ path: string;
+
+ // Owner
+ owner: string;
+
+ // Contact
+ contact: string;
+
+ // Notes
+ notes: string;
+
+ // Country Code
+ country_code: string;
+
+ // ASN
+ asn: number;
+
+ // Last Check Was Successful?
+ last_check_success: boolean;
+
+ // Last Check At
+ last_check_at: Date;
+
+ // Last Sync At
+ last_sync_at: Date;
+}
--- /dev/null
+<script setup lang="ts">
+ import { ref, onMounted } from "vue";
+ import type { Mirror } from "@/types/Mirror";
+ import { fetchMirrors } from "@/api/mirrors";
+
+ // Import UI components
+ import Section from "../components/Section.vue"
+
+ // Mirrors
+ const mirrors = ref<Mirror[]>([]);
+
+ // Fetch all builders as soon as we are mounted
+ onMounted(async () => {
+ try {
+ mirrors.value = await fetchMirrors();
+ } catch (err) {
+ console.error(err);
+ }
+ });
+</script>
+
+<template>
+ <Section :title="$t('Mirrors')">
+ <Container>
+ <div v-for="mirror in mirrors" class="box" :key="mirror.hostname">
+ <h5 class="title is-5">
+ {{ mirror.hostname }}
+ </h5>
+
+ <h6 class="subtitle is-6">
+ <span v-if="mirror.owner">
+ {{ mirror.owner }}
+ </span>
+ </h6>
+ </div>
+ </Container>
+ </Section>
+</template>