85 lines
3.4 KiB
TypeScript
85 lines
3.4 KiB
TypeScript
import { motion } from "motion/react";
|
|
import { Link } from "react-router-dom";
|
|
import { BLOG_POSTS } from "../lib/data";
|
|
|
|
const transition = { type: "spring", bounce: 0, duration: 0.8 };
|
|
|
|
export function Blog() {
|
|
return (
|
|
<div className="flex flex-col gap-12">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={transition}
|
|
className="flex flex-col gap-4"
|
|
>
|
|
<h1 className="text-3xl font-semibold tracking-tight text-white">
|
|
Artigos
|
|
</h1>
|
|
<p className="text-zinc-400 max-w-xl">
|
|
Explorações sobre desenvolvimento front-end, design de interfaces, arquitetura de software e tecnologia em geral.
|
|
</p>
|
|
</motion.div>
|
|
|
|
<div className="flex flex-col">
|
|
{BLOG_POSTS.map((post, i) => (
|
|
<motion.div
|
|
key={post.slug}
|
|
initial={{ opacity: 0, y: 10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ ...transition, delay: i * 0.1 }}
|
|
>
|
|
<Link
|
|
to={`/blog/${post.slug}`}
|
|
className="group flex flex-col sm:flex-row py-8 border-b border-white/[0.08] hover:bg-zinc-900/40 px-4 -mx-4 rounded-2xl transition-colors gap-6 sm:gap-8 items-start"
|
|
>
|
|
{post.coverImage && (
|
|
<div className="w-full sm:w-64 h-48 sm:h-40 shrink-0 rounded-xl overflow-hidden border border-zinc-800/80 hidden sm:block">
|
|
<img
|
|
src={post.coverImage}
|
|
alt={post.title}
|
|
className="w-full h-full object-cover grayscale group-hover:grayscale-0 transition-all duration-700 scale-100 group-hover:scale-105"
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className="flex flex-col flex-1">
|
|
{post.coverImage && (
|
|
<div className="w-full h-48 shrink-0 rounded-xl overflow-hidden border border-zinc-800/80 mb-4 sm:hidden">
|
|
<img
|
|
src={post.coverImage}
|
|
alt={post.title}
|
|
className="w-full h-full object-cover grayscale group-hover:grayscale-0 transition-all duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className="flex items-center gap-3 mb-3">
|
|
<time className="text-xs font-mono text-zinc-500">
|
|
{new Date(post.date).toLocaleDateString('pt-BR', { year: 'numeric', month: 'long', day: 'numeric' })}
|
|
</time>
|
|
<span className="w-1 h-1 rounded-full bg-zinc-800" />
|
|
<span className="text-xs font-mono text-zinc-500">{post.readTime}</span>
|
|
</div>
|
|
|
|
<h3 className="text-xl font-medium text-zinc-200 group-hover:text-white transition-colors mb-2">
|
|
{post.title}
|
|
</h3>
|
|
|
|
<p className="text-sm text-zinc-400 mb-4 max-w-2xl">
|
|
{post.excerpt}
|
|
</p>
|
|
|
|
<div className="flex flex-wrap gap-2 mt-auto">
|
|
{post.tags.map(tag => (
|
|
<span key={tag} className="px-2 py-1 bg-zinc-900 text-zinc-400 text-xs rounded-md border border-zinc-800 font-mono">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|