Add Homelab Page
This commit is contained in:
parent
6e53c65d3c
commit
cec63b729e
@ -2,4 +2,4 @@
|
||||
|
||||
My personal website and blog.
|
||||
|
||||
Vist the site at https://justin.deal
|
||||
Visit the site at https://justin.deal
|
19
src/components/common/ServiceCard.astro
Normal file
19
src/components/common/ServiceCard.astro
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
const { name, href, img, alt } = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
href={href}
|
||||
class="flex flex-col items-center transition-transform transform hover:scale-105 hover:opacity-90"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<img
|
||||
src={img}
|
||||
alt={alt}
|
||||
class="w-16 h-16"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<p class="mt-2 text-center">{name}</p>
|
||||
</a>
|
@ -39,6 +39,7 @@ export const GLOBAL = {
|
||||
home: "/",
|
||||
blog: "/blog",
|
||||
projects: "/projects",
|
||||
homelab: "/homelab",
|
||||
// about: "/about",
|
||||
// code: "https://code.justin.deal",
|
||||
// videos: "https://www.youtube.com/@justin_deal",
|
||||
|
@ -7,12 +7,4 @@ time: 4
|
||||
featured: true
|
||||
timestamp: 2024-12-18T02:39:03+00:00
|
||||
filename: html-intro
|
||||
---
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{tags.map((tag) => (
|
||||
<span class="-zag-text -zag-bg zag-transition px-2 py-1 text-sm font-semibold">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
---
|
52
src/pages/homelab/index.astro
Normal file
52
src/pages/homelab/index.astro
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
import { GLOBAL } from "../../lib/variables";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import Section from "../../components/common/Section.astro";
|
||||
import ServiceCard from "../../components/common/ServiceCard.astro";
|
||||
import { services } from "./services.ts";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<Fragment slot="head">
|
||||
<title>{GLOBAL.username} • {GLOBAL.shortDescription}</title>
|
||||
<meta name="description" content={GLOBAL.longDescription} />
|
||||
<meta property="og:title" content={`${GLOBAL.username} • ${GLOBAL.shortDescription}`} />
|
||||
<meta property="og:description" content={GLOBAL.longDescription} />
|
||||
<meta property="og:image" content={`${GLOBAL.rootUrl}/pixel_avatar.png`} />
|
||||
<meta property="og:url" content={GLOBAL.rootUrl} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={`${GLOBAL.username} • ${GLOBAL.shortDescription}`} />
|
||||
<meta name="twitter:description" content={GLOBAL.longDescription} />
|
||||
<meta name="twitter:image" content={`${GLOBAL.rootUrl}/pixel_avatar.png`} />
|
||||
<meta http-equiv="content-language" content="en" />
|
||||
<meta name="language" content="English" />
|
||||
<link rel="canonical" href={GLOBAL.rootUrl} />
|
||||
</Fragment>
|
||||
|
||||
<Section class="my-8">
|
||||
<div class="flex items-center gap-4 pt-8 pb-4">
|
||||
<h1 class="font-display text-3xl sm:text-4xl leading-loose">Homelab</h1>
|
||||
</div>
|
||||
|
||||
{Object.entries(services).map(([category, apps]) => (
|
||||
<div class="mb-8">
|
||||
<h3 class="text-xl font-semibold mb-4">{category}</h3>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
|
||||
{apps.length > 0 ? (
|
||||
apps.map(app => (
|
||||
<ServiceCard
|
||||
name={app.name}
|
||||
href={app.link}
|
||||
img={app.icon}
|
||||
alt={app.name}
|
||||
key={app.link}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<p class="text-center col-span-full">Coming soon...</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Section>
|
||||
</Layout>
|
126
src/pages/homelab/services.ts
Normal file
126
src/pages/homelab/services.ts
Normal file
@ -0,0 +1,126 @@
|
||||
export const services = {
|
||||
Websites: [
|
||||
{
|
||||
name: "https://justin.deal",
|
||||
link: "https://justin.deal",
|
||||
icon: "/public/pixel_avatar.png",
|
||||
alt: "Personal Website"
|
||||
}
|
||||
],
|
||||
Utilities: [
|
||||
{
|
||||
name: "Silverbullet",
|
||||
link: "https://notes.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/silverbullet.png",
|
||||
alt: "Silverbullet"
|
||||
},
|
||||
{
|
||||
name: "Vikunja",
|
||||
link: "https://todo.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/vikunja.svg",
|
||||
alt: "Vikunja"
|
||||
},
|
||||
{
|
||||
name: "Actual",
|
||||
link: "https://budget.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/actual-budget.svg",
|
||||
alt: "Actual"
|
||||
},
|
||||
{
|
||||
name: "Searxng",
|
||||
link: "https://search.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/searxng.svg",
|
||||
alt: "Searxng"
|
||||
},
|
||||
{
|
||||
name: "TeslaMate",
|
||||
link: "https://tesla.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/teslamate.svg",
|
||||
alt: "TeslaMate"
|
||||
},
|
||||
{
|
||||
name: "BaiKal",
|
||||
link: "https://dav.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/baikal.png",
|
||||
alt: "BaiKal"
|
||||
},
|
||||
{
|
||||
name: "Cryptpad",
|
||||
link: "https://docs.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/cryptpad.svg",
|
||||
alt: "Cryptpad"
|
||||
}
|
||||
],
|
||||
Development: [
|
||||
{
|
||||
name: "Gitea",
|
||||
link: "https://code.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/gitea.svg",
|
||||
alt: "Gitea"
|
||||
},
|
||||
{
|
||||
name: "OpenGist",
|
||||
link: "https://snippets.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/opengist.svg",
|
||||
alt: "OpenGist"
|
||||
},
|
||||
{
|
||||
name: "IT-Tools",
|
||||
link: "https://tools.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/it-tools.svg",
|
||||
alt: "IT-Tools"
|
||||
}
|
||||
],
|
||||
Media: [
|
||||
{
|
||||
name: "Jellyfin",
|
||||
link: "https://watch.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/jellyfin.svg",
|
||||
alt: "Jellyfin"
|
||||
},
|
||||
{
|
||||
name: "Calibre-Web",
|
||||
link: "https://books.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/calibre-web.svg",
|
||||
alt: "Calibre-Web"
|
||||
}
|
||||
],
|
||||
Infrastructure: [
|
||||
{
|
||||
name: "Pi-hole",
|
||||
link: "https://pihole.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/pi-hole.svg",
|
||||
alt: "Pi-hole"
|
||||
},
|
||||
{
|
||||
name: "Ntfy",
|
||||
link: "https://ntfy.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/ntfy.svg",
|
||||
alt: "Ntfy"
|
||||
},
|
||||
{
|
||||
name: "Vaultwarden",
|
||||
link: "https://passwords.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/vaultwarden.svg",
|
||||
alt: "Vaultwarden"
|
||||
},
|
||||
{
|
||||
name: "Uptime Kuma",
|
||||
link: "https://status.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/uptime-kuma.svg",
|
||||
alt: "Uptime Kuma"
|
||||
},
|
||||
{
|
||||
name: "Authentik",
|
||||
link: "https://auth.justin.deal",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/authentik.svg",
|
||||
alt: "Authentik"
|
||||
},
|
||||
{
|
||||
name: "Traefik",
|
||||
link: "https://proxy.justin.deal:8080",
|
||||
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/traefik.svg",
|
||||
alt: "Traefik"
|
||||
}
|
||||
]
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user