Files
website/src/components/project-article.tsx

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>
);
}