feat(homelab)!: create interface for homelab management, use templating for route generation & support more options and route types

This commit is contained in:
2026-01-11 14:57:19 -08:00
parent 29cff3bf84
commit 1f43dff2c5
46 changed files with 3908 additions and 109 deletions

View File

@@ -0,0 +1,26 @@
<script lang="ts">
import { Button } from "bits-ui";
function syncCreativeWorld() {
console.log("Syncing creative world...");
}
function backupMainWorld() {
console.log("Backing up main world...");
}
</script>
<div class="flex gap-3 mb-6">
<Button.Root
onclick={syncCreativeWorld}
class="bg-[#7aa2f7] hover:bg-[#7dcfff]"
>
Sync Creative World
</Button.Root>
<Button.Root
onclick={backupMainWorld}
class="bg-[#bb9af7] hover:bg-[#c0caf5]"
>
Backup Main World
</Button.Root>
</div>

View File

@@ -0,0 +1,37 @@
<script lang="ts">
import { createQuery } from "@tanstack/svelte-query";
import { fetchStats } from "./stats";
import { LoaderCircle } from "@lucide/svelte";
const query = createQuery(() => ({
queryKey: ["minecraft-server-stats"],
queryFn: () => fetchStats(),
refetchInterval: 10000,
staleTime: 5000,
}));
</script>
{#snippet statItem(label: string, value?: string | number)}
<div class="bg-zinc-700 rounded p-3">
<div class="text-sm">{label}</div>
<div class="text-xl text-white">{value}</div>
</div>
{/snippet}
<div class="border border-zinc-600 rounded-lg p-4">
<h3 class="text-lg font-medium mb-3">
Server Stats {#if query.isError}
<span class="text-sm text-red-500"
>an error occured fetching server stats</span
>
{:else if query.isPending}
<LoaderCircle class="ml-1 w-4 h-4 inline-block animate-spin" />
{/if}
</h3>
<div class="grid grid-cols-2 gap-4 text-zinc-400">
{@render statItem("Players Online", query.data?.players_online ?? "--")}
{@render statItem("Server Status", query.data?.status ?? "--")}
{@render statItem("Uptime", query.data?.uptime ?? "--")}
{@render statItem("World Size", query.data?.world_size ?? "--")}
</div>
</div>

View File

@@ -0,0 +1,14 @@
type StatsResponse = {
status: string;
players_online: number;
max_players: number;
uptime: string;
world_size: string;
};
export const fetchStats = async () => {
const response = await fetch(
"http://localhost:5173/api/minecraft-server-stats",
);
return (await response.json()) as StatsResponse;
};