Tecnologia/Template-01/src/pages/PostDetail.tsx

200 lines
9.8 KiB
TypeScript
Raw Normal View History

2026-05-13 22:24:26 +00:00
import React from 'react';
import { useParams, Link } from 'react-router-dom';
import { useI18n } from '../hooks/useI18n';
import { SEO } from '../components/SEO';
import { TableOfContents } from '../components/TableOfContents';
import { Newsletter } from '../components/Newsletter';
import { PostCard } from '../components/PostCard';
import { formatDate } from '../lib/utils';
import { ArrowLeft, Clock, Twitter, Linkedin, Link as LinkIcon, Cpu, Terminal } from 'lucide-react';
import { motion } from 'motion/react';
import Markdown from 'react-markdown';
export default function PostDetail() {
const { slug } = useParams<{ slug: string }>();
const { lang, posts, t } = useI18n();
const validPosts = posts || [];
const post = validPosts.find(p => p.slug === slug);
const relatedPosts = validPosts.filter(p => p.slug !== slug && (p.category === post?.category || p.featured)).slice(0, 3);
if (!post) {
return (
<div className="container mx-auto px-6 py-40 text-center font-mono uppercase tracking-widest text-tech-muted">
<h1 className="text-4xl font-bold mb-8 text-tech-text">[error] 404_NOT_FOUND</h1>
<Link to={`/${lang}/blog`} className="text-tech-primary inline-flex items-center gap-2 font-bold bg-tech-surface px-6 py-2 rounded">
<ArrowLeft size={16} /> RETURN_TO_BASE
</Link>
</div>
);
}
return (
<div className="bg-white min-h-screen">
<SEO
title={post.title}
description={post.description}
image={post.image}
article
author={post.author}
datePublished={post.date}
category={post.category}
/>
{/* Technical Header */}
<section className="pt-32 pb-16 relative bg-white border-b border-slate-100">
<div className="container mx-auto px-6 lg:px-12 relative z-10">
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
>
<Link to={`/${lang}/blog`} className="inline-flex items-center gap-2 text-tech-muted text-[10px] font-mono font-bold mb-8 hover:text-tech-text transition-colors uppercase tracking-widest">
<ArrowLeft size={12} /> cd ../blog
</Link>
<div className="flex items-center gap-3 mb-8">
<span className="category-tag">
{post.category}
</span>
<div className="w-1 h-1 rounded-full bg-tech-border" />
<span className="text-tech-muted text-[10px] uppercase font-mono font-bold tracking-widest flex items-center gap-1">
<Clock size={10} /> READ_TIME: {post.readingTime}
</span>
</div>
<h1 className="text-4xl md:text-5xl lg:text-7xl font-extrabold text-tech-text leading-[1] tracking-tighter mb-8 max-w-5xl">
{post.title}
</h1>
<p className="text-lg md:text-xl text-tech-muted mb-12 max-w-3xl leading-relaxed font-medium">
{post.description}
</p>
<div className="flex flex-col md:flex-row items-center gap-6 pt-8 border-t border-tech-border">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded bg-tech-surface flex items-center justify-center font-mono font-bold text-tech-muted border border-tech-border">
{post.author[0]}
</div>
<div className="text-left leading-tight">
<span className="font-bold text-tech-text block text-sm">{post.author}</span>
<span className="text-tech-muted text-[10px] font-mono font-bold uppercase">system_editor</span>
</div>
</div>
<div className="hidden md:block h-8 w-px bg-tech-border" />
<div className="text-left leading-tight">
<span className="text-tech-muted text-[10px] font-mono font-bold uppercase block">timestamp</span>
<span className="font-bold text-tech-text text-sm">{formatDate(post.date, lang)}</span>
</div>
</div>
</motion.div>
</div>
</section>
{/* Featured Technical Image */}
<section className="container mx-auto px-6 lg:px-12 py-12">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.1 }}
className="aspect-video lg:aspect-[21/7] rounded-lg overflow-hidden border border-tech-border bg-tech-surface relative"
>
<img src={post.image} className="w-full h-full object-cover opacity-90 transition-opacity hover:opacity-100" alt={post.title} referrerPolicy="no-referrer" />
<div className="absolute bottom-4 right-4 bg-tech-text/80 backdrop-blur-md px-3 py-1 rounded text-[10px] font-mono text-white border border-slate-700 uppercase">IMG_REF: {post.slug}.jpg</div>
</motion.div>
</section>
{/* Content Section */}
<section className="container mx-auto px-6 lg:px-12 pb-32">
<div className="grid grid-cols-1 lg:grid-cols-[1fr_300px] gap-16">
{/* Main Article body */}
<article className="markdown-body w-full max-w-3xl border-r border-slate-50 pr-0 lg:pr-16">
<Markdown>{post.content}</Markdown>
</article>
{/* Sidebar */}
<aside className="space-y-12">
<div className="sticky top-32">
<TableOfContents content={post.content} />
<div className="mt-8 p-6 bg-tech-surface rounded border border-tech-border">
<h4 className="text-[10px] font-mono font-bold uppercase tracking-widest text-tech-muted mb-4">./bio_metadata</h4>
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 rounded bg-white flex items-center justify-center font-bold text-tech-muted border border-tech-border">
{post.author[0]}
</div>
<div>
<span className="font-bold text-tech-text block text-sm">{post.author}</span>
<span className="text-tech-primary text-[10px] font-mono font-bold uppercase">@alex_nexus</span>
</div>
</div>
<p className="text-xs text-tech-muted leading-relaxed font-medium">
Technical architect with 10+ years optimizing distributed systems and multimodal AI agents.
</p>
</div>
<div className="mt-8 flex flex-col gap-2">
<div className="text-[10px] font-mono font-bold text-tech-muted uppercase tracking-widest mb-2">Compartilhar_Modulo</div>
<div className="flex gap-2">
<a
href={`https://twitter.com/intent/tweet?text=${encodeURIComponent(post.title)}&url=${encodeURIComponent(window.location.href)}`}
target="_blank"
rel="noopener noreferrer"
className="w-8 h-8 rounded bg-white border border-tech-border flex items-center justify-center text-tech-muted hover:text-tech-primary hover:border-tech-primary transition-all cursor-pointer"
>
<Twitter size={14} />
</a>
<a
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(window.location.href)}`}
target="_blank"
rel="noopener noreferrer"
className="w-8 h-8 rounded bg-white border border-tech-border flex items-center justify-center text-tech-muted hover:text-tech-primary hover:border-tech-primary transition-all cursor-pointer"
>
<Linkedin size={14} />
</a>
<button
onClick={() => {
navigator.clipboard.writeText(window.location.href);
alert('Link copiado!');
}}
className="w-8 h-8 rounded bg-white border border-tech-border flex items-center justify-center text-tech-muted hover:text-tech-text hover:border-tech-text transition-all cursor-pointer"
>
<LinkIcon size={14} />
</button>
</div>
</div>
</div>
</aside>
</div>
</section>
{/* Related Technical Modules */}
{relatedPosts.length > 0 && (
<section className="py-24 bg-tech-surface border-t border-tech-border">
<div className="container mx-auto px-6 lg:px-12">
<div className="flex items-center justify-between mb-12">
<div>
<div className="flex items-center gap-2 text-tech-primary text-[10px] font-mono font-bold uppercase tracking-widest mb-4">
<div className="w-8 h-px bg-tech-primary" />
<span>REL_MODULES</span>
</div>
<h2 className="text-3xl font-bold tracking-tight text-tech-text">Módulos Relacionados</h2>
</div>
<Link to={`/${lang}/blog`} className="text-[10px] font-mono font-bold text-tech-muted hover:text-tech-text transition-colors uppercase tracking-widest border border-tech-border px-4 py-2 rounded">view_all_entries</Link>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-0 border-t border-l border-tech-border">
{relatedPosts.map(post => (
<div key={post.id} className="border-r border-b border-tech-border p-1 bg-white">
<PostCard post={post} />
</div>
))}
</div>
</div>
</section>
)}
<Newsletter />
</div>
);
}