Files
portfolio/app/[[...slug]]/page.tsx
T

53 lines
1.4 KiB
TypeScript
Raw Normal View History

import { notFound } from 'next/navigation';
import type { SectionRecord } from '$entities/Section';
import { getCollection } from '$shared/api';
import { SectionFactory } from '$widgets/SectionFactory';
import { SectionsAccordion } from '$widgets/SectionsAccordion';
/**
* Optional catchall: `/` → first section, `/:slug` → that section.
*/
export async function generateStaticParams() {
const { items: sections } = await getCollection<SectionRecord>('sections', {
sort: 'order',
tags: ['sections'],
});
return [{}, ...sections.map((s) => ({ slug: [s.slug] }))];
}
type Props = {
params: Promise<{ slug?: string[] }>;
};
/**
* Portfolio page — one route per section, sections list always visible.
*/
export default async function SectionPage({ params }: Props) {
const { slug } = await params;
const { items: sections } = await getCollection<SectionRecord>('sections', {
sort: 'order',
tags: ['sections'],
});
if (sections.length === 0) {
notFound();
}
const activeSlug = slug?.[0] ?? sections[0].slug;
if (!sections.some((s) => s.slug === activeSlug)) {
notFound();
}
return (
<main className="px-8 py-12 lg:py-16 lg:px-16">
<SectionsAccordion sections={sections} activeSlug={activeSlug}>
{sections.map((s) => (
<SectionFactory key={s.slug} slug={s.slug} />
))}
</SectionsAccordion>
</main>
);
}