Files
techzaa-frontend/src/components/home/BlogSection.tsx
T

148 lines
5.1 KiB
TypeScript

import { Button } from "@/components/ui/button";
import { useBlogs } from "@/hooks/queires/useBlogs";
import { motion } from "framer-motion";
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
import { Link } from "react-router-dom";
import PremiumBadge from "../shared/PremiumBadge";
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 30 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.6, ease: "easeOut" as const },
},
};
export default function BlogSection() {
const { data } = useBlogs();
const blogPosts = data?.data.result;
return (
<section id="blog" className=" pt-20 relative overflow-hidden">
{/* Background elements */}
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-primary/5 to-transparent" />
<div className="container mx-auto px-4 relative z-10">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="text-center mb-16"
>
<PremiumBadge text="Latest Insights" />
<h2 className="text-4xl md:text-5xl font-bold mb-6">
News &{" "}
<span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-sidebar-primary">
Blog
</span>
</h2>
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
Stay updated with the latest trends, insights, and thought
leadership from our team of experts.
</p>
</motion.div>
{/* Blog Grid */}
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
className="grid md:grid-cols-2 lg:grid-cols-3 gap-8"
>
{blogPosts?.map((post) => (
<motion.article
key={post._id}
variants={itemVariants}
className="group glass rounded-2xl overflow-hidden hover:neon-glow transition-all duration-500"
>
{/* Image */}
<div className="relative h-48 overflow-hidden">
<img
src={post.image}
alt={post.title}
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
/>
<div className="absolute inset-0 bg-gradient-to-t from-background/80 to-transparent" />
<span className="absolute bottom-4 left-4 px-3 py-1 rounded-full bg-primary/20 text-primary text-xs font-medium backdrop-blur-sm">
{post.category}
</span>
</div>
{/* Content */}
<div className="p-6">
<h3 className="text-xl font-bold mb-3 group-hover:text-primary transition-colors line-clamp-2">
{post.title}
</h3>
<p className="text-muted-foreground text-sm mb-4 line-clamp-2">
{post.excerpt}
</p>
{/* Meta */}
<div className="flex items-center gap-4 text-xs text-muted-foreground mb-4">
<span className="flex items-center gap-1">
<User className="w-3 h-3" />
{post.author.name}
</span>
<span className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
{new Date(post.date).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
})}
</span>
<span className="flex items-center gap-1">
<Clock className="w-3 h-3" />
{post.readTime}
</span>
</div>
{/* Read More */}
<Link
to={`/blog/${post._id}`}
className="inline-flex items-center gap-2 text-primary font-medium text-sm group/link hover:gap-3 transition-all"
>
Read Article
<ArrowRight className="w-4 h-4" />
</Link>
</div>
</motion.article>
))}
</motion.div>
{/* View All Button */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: 0.4 }}
className="text-center mt-12"
>
<Link to="/blog">
<Button
variant="outline"
className="font-semibold px-8 py-6 text-lg rounded-full border-primary bg-primary/10 transition-all"
>
View All Articles
<ArrowRight className="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" />
</Button>
</Link>
</motion.div>
</div>
</section>
);
}