diff --git a/app/page.tsx b/app/page.tsx index 419da6b..8b4e579 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,51 +1,37 @@ -import Image from 'next/image'; +import type { SectionRecord } from '$entities/Section'; +import { getCollection } from '$shared/api'; +import type { NavItem } from '$widgets/Navigation'; +import { MobileNav, SidebarNav } from '$widgets/Navigation'; +import { SectionFactory } from '$widgets/SectionFactory'; +import { SectionsAccordion } from '$widgets/SectionsAccordion'; + +/** + * Portfolio home page. + * + * Fetches all sections at build time (SSG). Renders a fixed sidebar with + * section navigation and a scrollable main column with accordion sections. + */ +export default async function Home() { + const { items: sections } = await getCollection('sections', { + sort: 'order', + }); + + const navItems: NavItem[] = sections.map((s) => ({ + id: s.slug, + label: s.title, + number: s.number, + })); -export default function Home() { return ( -
-
- Next.js logo -
-

- To get started, edit the page.tsx file. -

-

- Looking for a starting point or more instructions? Head over to{' '} - - Templates - {' '} - or the{' '} - - Learning - {' '} - center. -

-
-
- - Vercel logomark - Deploy Now - - - Documentation - -
+
+ +
+ + + {sections.map((s) => ( + + ))} +
); diff --git a/src/entities/project/ui/ProjectMetadata.test.tsx b/src/entities/project/ui/ProjectMetadata.test.tsx index ef5770b..363997e 100644 --- a/src/entities/project/ui/ProjectMetadata.test.tsx +++ b/src/entities/project/ui/ProjectMetadata.test.tsx @@ -50,19 +50,19 @@ describe('ProjectMetadata', () => { it('year section has no brutal-border-top (first section)', () => { const { container } = render(); - const sections = container.firstChild?.childNodes; + const sections = container.firstChild?.childNodes as NodeListOf; expect(sections[0]).not.toHaveClass('brutal-border-top'); }); it('role section has brutal-border-top and pt-6', () => { const { container } = render(); - const sections = container.firstChild?.childNodes; + const sections = container.firstChild?.childNodes as NodeListOf; expect(sections[1]).toHaveClass('brutal-border-top', 'pt-6'); }); it('stack section has brutal-border-top and pt-6', () => { const { container } = render(); - const sections = container.firstChild?.childNodes; + const sections = container.firstChild?.childNodes as NodeListOf; expect(sections[2]).toHaveClass('brutal-border-top', 'pt-6'); }); diff --git a/src/shared/lib/utils/groupByKey/groupByKey.test.ts b/src/shared/lib/utils/groupByKey/groupByKey.test.ts index fad0754..f7bfb14 100644 --- a/src/shared/lib/utils/groupByKey/groupByKey.test.ts +++ b/src/shared/lib/utils/groupByKey/groupByKey.test.ts @@ -22,7 +22,7 @@ describe('groupByKey', () => { { category: 'A', order: 1 }, { category: 'A', order: 2 }, ]; - expect(groupByKey(items, 'category')['A']).toEqual([ + expect(groupByKey(items, 'category').A).toEqual([ { category: 'A', order: 1 }, { category: 'A', order: 2 }, ]); @@ -41,7 +41,7 @@ describe('groupByKey', () => { ]; const result = groupByKey(items, 'type'); expect(Object.keys(result)).toHaveLength(1); - expect(result['X']).toHaveLength(2); + expect(result.X).toHaveLength(2); }); it('handles single item', () => {