fix: storybook font rendering and shared fonts module #1
@@ -0,0 +1,50 @@
|
||||
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',
|
||||
});
|
||||
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',
|
||||
});
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
const base = { created: '', updated: '' };
|
||||
|
||||
@@ -241,6 +241,10 @@ const FIXTURES: Record<string, unknown[]> = {
|
||||
],
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return Object.keys(FIXTURES).map((collection) => ({ collection }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock API route handler for PocketBase collection records.
|
||||
* Returns fixture data shaped as a PocketBase list response.
|
||||
|
||||
+4
-3
@@ -1,10 +1,11 @@
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
const isExport = process.env.NODE_ENV === 'production';
|
||||
/* output: 'export' is opt-in via STATIC_EXPORT=true.
|
||||
* Set this in CI/deploy — not locally — so the mock API route works
|
||||
* during development and local builds. */
|
||||
const isExport = process.env.STATIC_EXPORT === 'true';
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* output: 'export' only applies at build time — enabling it in dev mode
|
||||
* breaks route handlers (incompatible with force-dynamic in Next.js 16) */
|
||||
...(isExport ? { output: 'export' } : {}),
|
||||
images: { unoptimized: true },
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"export": "STATIC_EXPORT=true next build",
|
||||
"start": "next start",
|
||||
"lint": "biome lint --write .",
|
||||
"format": "biome format --write .",
|
||||
|
||||
Reference in New Issue
Block a user