feat: portfolio with subpages, hero homepage, and obfuscated asset URLs
This commit is contained in:
123
app/page.tsx
123
app/page.tsx
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user