fix: storybook font rendering and shared fonts module #1

Merged
ilia merged 74 commits from feat/portfolio-setup into main 2026-05-18 18:45:22 +00:00
4 changed files with 60 additions and 4 deletions
Showing only changes of commit fed9c97ddb - Show all commits
+50
View File
@@ -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'; import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic'; export const dynamic = 'force-static';
const base = { created: '', updated: '' }; 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. * Mock API route handler for PocketBase collection records.
* Returns fixture data shaped as a PocketBase list response. * Returns fixture data shaped as a PocketBase list response.
+4 -3
View File
@@ -1,10 +1,11 @@
import type { NextConfig } from 'next'; 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 = { 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' } : {}), ...(isExport ? { output: 'export' } : {}),
images: { unoptimized: true }, images: { unoptimized: true },
}; };
+1
View File
@@ -5,6 +5,7 @@
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"export": "STATIC_EXPORT=true next build",
"start": "next start", "start": "next start",
"lint": "biome lint --write .", "lint": "biome lint --write .",
"format": "biome format --write .", "format": "biome format --write .",