hotschpotsh/Pottery-website/components/BlogPostLayout.tsx

113 lines
5.2 KiB
TypeScript

import React, { useEffect } from 'react';
import { motion } from 'framer-motion';
import { Link } from 'react-router-dom';
import { useStore } from '../src/context/StoreContext';
interface BlogPostLayoutProps {
title: string;
category: string;
date: string;
image: string;
imageAlt: string;
children: React.ReactNode;
}
const BlogPostLayout: React.FC<BlogPostLayoutProps> = ({
title,
category,
date,
image,
imageAlt,
children,
}) => {
const { articles } = useStore();
// Scroll to top on mount
useEffect(() => {
window.scrollTo(0, 0);
}, []);
const nextArticles = articles.filter(post => post.title !== title).slice(0, 2);
return (
<div className="bg-stone-50 dark:bg-black min-h-screen font-body transition-colors duration-500">
<main className="pt-32 pb-24">
{/* Article Header */}
<article className="max-w-4xl mx-auto px-6 md:px-12">
<div className="flex items-center space-x-4 mb-8 justify-center">
<span className="text-xs uppercase tracking-[0.2em] text-text-muted border border-text-muted/30 px-3 py-1 rounded-full">{category}</span>
<span className="text-xs uppercase tracking-[0.2em] text-text-muted">{date}</span>
</div>
<motion.h1
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className="font-display text-5xl md:text-6xl lg:text-7xl text-center text-text-main dark:text-white mb-16 leading-tight"
>
{title}
</motion.h1>
{/* Hero Image */}
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
className="w-full h-[40vh] md:h-[50vh] relative mb-16 overflow-hidden shadow-xl rounded-sm"
>
<img
src={image}
alt={imageAlt}
className="w-full h-full object-cover"
/>
</motion.div>
{/* Content Container */}
<div className="prose prose-stone dark:prose-invert max-w-none mx-auto prose-headings:font-display prose-headings:font-light prose-p:font-light prose-p:leading-loose prose-a:text-terracotta hover:prose-a:text-terracotta-dark prose-img:rounded-sm">
{children}
</div>
{/* Read Next Section */}
{nextArticles.length > 0 && (
<div className="mt-24 pt-16 border-t border-stone-200 dark:border-stone-800">
<h3 className="font-display text-3xl text-center mb-12 text-text-main dark:text-white">Read Next</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
{nextArticles.map((post) => (
<Link key={post.id} to={`/editorial/${post.slug}`} className="group block">
<div className="aspect-[3/2] overflow-hidden bg-stone-100 mb-4">
<img
src={post.image}
alt={post.title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
/>
</div>
<h4 className="font-display text-2xl text-text-main dark:text-white group-hover:underline decoration-1 underline-offset-4 mb-2">
{post.title}
</h4>
<div className="flex items-center space-x-2 text-sm text-stone-500 uppercase tracking-widest">
<span>{post.category}</span>
<span></span>
<span>{post.date}</span>
</div>
</Link>
))}
</div>
</div>
)}
{/* Back Link */}
<div className="mt-20 text-center">
<Link to="/editorial" className="inline-block border-b border-black dark:border-white pb-1 text-sm uppercase tracking-widest hover:text-stone-500 transition-colors">
Back to Editorial
</Link>
</div>
</article>
</main>
</div>
);
};
export default BlogPostLayout;