65 lines
2.5 KiB
Plaintext
65 lines
2.5 KiB
Plaintext
---
|
|
import { GLOBAL } from "../../lib/variables";
|
|
import Layout from "../../layouts/Layout.astro";
|
|
import Section from "../../components/common/Section.astro";
|
|
import SearchBar from "../../components/common/SearchBar.astro";
|
|
import CategorySection from "../../components/homelab/CategorySection.astro";
|
|
import { services } from "./services.ts";
|
|
import { initializeSearch } from "../../components/common/searchUtils.js";
|
|
---
|
|
|
|
<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>
|
|
|
|
<!-- Search functionality is provided by search-client.js -->
|
|
|
|
<Section class="my-8">
|
|
<div x-data="searchServices" x-init="init()">
|
|
<!-- Search container - positioned at the top -->
|
|
<div class="mb-4 pt-0">
|
|
<div class="w-full">
|
|
<SearchBar
|
|
placeholder="Search services..."
|
|
ariaLabel="Search services"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Page heading - now below search -->
|
|
<div class="flex items-center gap-4 pb-4 mt-2">
|
|
<h1 class="font-display text-3xl sm:text-4xl leading-loose">Homelab</h1>
|
|
</div>
|
|
|
|
<!-- No results message -->
|
|
<div
|
|
x-show="searchQuery !== '' && !hasResults"
|
|
x-transition
|
|
class="text-center py-8 my-4 border-2 border-dashed border-current zag-text rounded-lg"
|
|
>
|
|
<p class="text-xl font-semibold zag-text">No Results</p>
|
|
</div>
|
|
|
|
<!-- Service categories -->
|
|
<div id="app-list">
|
|
{Object.entries(services).map(([category, apps]) => (
|
|
<CategorySection category={category} apps={apps} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Section>
|
|
</Layout>
|