feat: portfolio with subpages, hero homepage, and obfuscated asset URLs

This commit is contained in:
ralksta
2026-02-14 00:59:57 +01:00
parent 688a28c7df
commit 415aef98f2
20 changed files with 2231 additions and 123 deletions

View File

@@ -1,66 +1,69 @@
import Image from "next/image";
import styles from "./page.module.css";
/**
* Homepage — Split hero layout.
* Left panel: site title, subtitle, navigation links.
* Right panel: hero image from Immich.
*/
import Link from 'next/link';
import { immich } from '@/lib/immich';
import { getConfig } from '@/lib/config';
import { imageUrl } from '@/lib/urls';
// Render at request time — requires live Immich connection
export const dynamic = 'force-dynamic';
export default async function HomePage() {
const config = getConfig();
const [subpages, albums] = await Promise.all([
immich.getSubpages(),
immich.getStandaloneAlbums(),
]);
export default function Home() {
return (
<div className={styles.page}>
<main className={styles.main}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className={styles.intro}>
<h1>To get started, edit the page.tsx file.</h1>
<p>
Looking for a starting point or more instructions? Head over to{" "}
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Templates
</a>{" "}
or the{" "}
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Learning
</a>{" "}
center.
</p>
<div className="hero">
{/* ── Left Panel ──────────────────────────────── */}
<div className="hero__left">
<div className="hero__content">
<h1 className="hero__title">{config.siteTitle}</h1>
{config.siteSubtitle && (
<p className="hero__subtitle">{config.siteSubtitle}</p>
)}
<nav className="hero__nav">
{subpages.map((sp) => (
<Link
key={sp.slug}
href={`/${sp.slug}`}
className="hero__nav-link"
>
{sp.name}
</Link>
))}
{albums.map((album) => (
<Link
key={album.id}
href={`/${album.slug}`}
className="hero__nav-link"
>
{album.albumName}
</Link>
))}
</nav>
</div>
<div className={styles.ctas}>
<a
className={styles.primary}
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className={styles.logo}
src="/vercel.svg"
alt="Vercel logomark"
width={16}
height={16}
/>
Deploy Now
</a>
<a
className={styles.secondary}
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
</div>
</main>
</div>
{/* ── Right Panel (Hero Image) ────────────────── */}
<div className="hero__right">
{config.heroImage ? (
<img
src={imageUrl(config.heroImage, 'preview')}
alt=""
className="hero__image"
/>
) : (
<div className="hero__image-placeholder" />
)}
</div>
</div>
);
}