Initial commit: homelab dashboard
Elixir + Phoenix dashboard displaying public and internal homelab services. Internal services are shown only when the request originates from the local network, detected server-side via conn.remote_ip with Traefik trusted as a proxy (RemoteIp plug). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<Layouts.flash_group flash={@flash} />
|
||||
<div class="min-h-screen bg-base-100">
|
||||
<header class="border-b border-base-300 bg-base-200">
|
||||
<div class="mx-auto max-w-5xl px-6 py-6 flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="hero-home h-7 w-7 text-primary"></span>
|
||||
<h1 class="text-xl font-bold tracking-tight">Homelab Dashboard</h1>
|
||||
</div>
|
||||
<Layouts.theme_toggle />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="mx-auto max-w-5xl px-6 py-10 space-y-10">
|
||||
<section>
|
||||
<h2 class="text-xs font-semibold uppercase tracking-widest text-base-content/50 mb-4">
|
||||
Public Services
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<%= for service <- @public_services do %>
|
||||
<a
|
||||
href={service.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="group flex items-start gap-4 rounded-box bg-base-200 p-5 transition hover:bg-base-300 hover:shadow-md"
|
||||
>
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-btn bg-primary/10 text-primary group-hover:bg-primary/20 transition">
|
||||
<span class={[service.icon, "h-5 w-5"]}></span>
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-semibold"><%= service.name %></span>
|
||||
<span class="hero-arrow-top-right-on-square h-3.5 w-3.5 text-base-content/30 group-hover:text-primary transition"></span>
|
||||
</div>
|
||||
<p class="mt-0.5 text-sm text-base-content/60 leading-snug"><%= service.description %></p>
|
||||
</div>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<%= if @show_internal do %>
|
||||
<section>
|
||||
<div class="flex items-center gap-3 mb-4">
|
||||
<h2 class="text-xs font-semibold uppercase tracking-widest text-base-content/50">
|
||||
Internal Services
|
||||
</h2>
|
||||
<span class="badge badge-success badge-sm gap-1">
|
||||
<span class="inline-block h-1.5 w-1.5 rounded-full bg-success-content"></span>
|
||||
Local network
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<%= for service <- @internal_services do %>
|
||||
<a
|
||||
href={service.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="group flex items-start gap-4 rounded-box bg-base-200 p-5 transition hover:bg-base-300 hover:shadow-md"
|
||||
>
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-btn bg-secondary/10 text-secondary group-hover:bg-secondary/20 transition">
|
||||
<span class={[service.icon, "h-5 w-5"]}></span>
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-semibold"><%= service.name %></span>
|
||||
<span class="hero-arrow-top-right-on-square h-3.5 w-3.5 text-base-content/30 group-hover:text-secondary transition"></span>
|
||||
</div>
|
||||
<p class="mt-0.5 text-sm text-base-content/60 leading-snug"><%= service.description %></p>
|
||||
</div>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
</main>
|
||||
</div>
|
||||
Reference in New Issue
Block a user