100 lines
3.5 KiB
TypeScript
100 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { CitationProvider } from '@/context/citation-context';
|
|
import { ReferencesContainer } from '@/components/references-container';
|
|
import Image from 'next/image';
|
|
import { CustomMDX } from '@/components/custom-mdx';
|
|
import Link from 'next/link';
|
|
import { Publication } from '@/lib/publications';
|
|
import { useAccentColor } from '@/context/accent-color-context';
|
|
import { ProjectNavigation } from './project-navigation';
|
|
|
|
// Define the types for our props
|
|
interface Post {
|
|
source: any;
|
|
frontmatter: {
|
|
title: string;
|
|
excerpt?: string;
|
|
teaser?: string;
|
|
tags?: string[];
|
|
icon?: string;
|
|
};
|
|
}
|
|
|
|
interface NavigationLink {
|
|
slug: string;
|
|
title: string;
|
|
}
|
|
|
|
interface ProjectArticleProps {
|
|
post: Post;
|
|
publications: Publication[];
|
|
navigation: {
|
|
prev: NavigationLink | null;
|
|
next: NavigationLink | null;
|
|
};
|
|
basePath: string;
|
|
}
|
|
|
|
export function ProjectArticle({ post, publications, navigation, basePath }: ProjectArticleProps) {
|
|
const accentColor = useAccentColor();
|
|
|
|
return (
|
|
<CitationProvider publications={publications}>
|
|
<main className="flex flex-col min-h-[100dvh] py-8" style={{ '--accent-color': accentColor } as React.CSSProperties}>
|
|
<article className="prose prose-stone dark:prose-invert max-w-none">
|
|
<header className="mb-8">
|
|
<h1 className="text-4xl font-bold tracking-tighter sm:text-5xl mb-2">
|
|
{post.frontmatter.title}
|
|
</h1>
|
|
{post.frontmatter.excerpt && (
|
|
<p className="text-lg text-muted-foreground mt-1">{post.frontmatter.excerpt}</p>
|
|
)}
|
|
</header>
|
|
|
|
{post.frontmatter.tags && (
|
|
<div className="flex flex-wrap gap-2 mt-8">
|
|
{post.frontmatter.tags.map((tag: string) => (
|
|
<Link
|
|
key={tag}
|
|
href={`/tags/${tag}`}
|
|
className="px-3 py-1 text-sm font-medium bg-secondary text-secondary-foreground hover:text-primary-foreground transition-colors"
|
|
onMouseOver={(e) => e.currentTarget.style.backgroundColor = accentColor}
|
|
onMouseOut={(e) => e.currentTarget.style.backgroundColor = ''}
|
|
>
|
|
{tag}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{/* --- FIX IS HERE: Reverted to the float-based layout for proper text wrapping --- */}
|
|
<div className="mt-8">
|
|
{post.frontmatter.icon ? (
|
|
// Using a div with a clearing utility ('flow-root') is a robust way to contain floats.
|
|
<div className="flow-root">
|
|
<Image
|
|
src={post.frontmatter.icon}
|
|
alt={`${post.frontmatter.title} icon`}
|
|
width={80}
|
|
height={80}
|
|
className="md:block float-left mr-4 mb-2"
|
|
/>
|
|
<CustomMDX {...post.source} />
|
|
</div>
|
|
) : (
|
|
// If no icon, fall back to the original large first-letter layout
|
|
<div className="first-letter:float-left first-letter:mr-3 first-letter:text-5xl first-letter:font-bold first-letter:leading-none first-letter:text-primary first-letter:pr-1">
|
|
<CustomMDX {...post.source} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<ReferencesContainer />
|
|
|
|
<ProjectNavigation prev={navigation.prev} next={navigation.next} basePath={basePath} />
|
|
</article>
|
|
</main>
|
|
</CitationProvider>
|
|
);
|
|
} |