Files
portifolio-evandrodevbr/app/components/Projects.tsx
T
¨evandrodevbr¨ 780fd7c161 feat(ui): enhance contact form messaging and particle background animation
- Improved the contact form's message generation with more professional and detailed templates
- Replaced the grid-based background animation with a WebGL-powered particle system using OGL
- Added GSAP for advanced animation capabilities
- Adjusted layout styling for better centering and spacing across components
- Enhanced visual feedback and interactivity of the animated background

This change significantly upgrades the user experience and visual appeal of the contact section while maintaining performance through efficient rendering techniques.
2025-09-03 00:51:29 -03:00

135 lines
4.7 KiB
TypeScript

"use client";
import { motion } from "motion/react";
import { BentoGrid, BentoGridItem } from "@/components/magicui/bento-grid";
import { ExternalLink, Github } from "lucide-react";
import { usePortfolioData } from "@/lib/usePortfolioData";
export default function Projects() {
const { data, loading, error } = usePortfolioData();
if (loading) {
return (
<section id="projects" className="py-20 px-4">
<div className="max-w-6xl mx-auto text-center">
<div className="animate-pulse">
<div className="h-8 bg-gray-700 rounded w-1/3 mx-auto mb-4"></div>
<div className="h-4 bg-gray-700 rounded w-1/2 mx-auto"></div>
</div>
</div>
</section>
);
}
if (error || !data) {
return (
<section id="projects" className="py-20 px-4">
<div className="max-w-6xl mx-auto text-center">
<p className="text-red-400">Erro ao carregar dados de projetos.</p>
</div>
</section>
);
}
const projects = data.projects.filter((project) => project.featured);
return (
<section id="projects" className="py-20 px-4 mx-auto">
<div className="max-w-6xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className="text-center mb-16"
>
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Projetos em Destaque
</h2>
<p className="text-xl text-gray-300 max-w-2xl mx-auto">
Alguns dos projetos que desenvolvi, demonstrando minhas habilidades
e paixão por tecnologia
</p>
</motion.div>
<BentoGrid className="gap-6">
{projects.map((project, index) => (
<BentoGridItem
key={project.id}
colSpan={index === 0 ? 2 : 1}
className="group hover:scale-[1.02] transition-all duration-300 hover:shadow-2xl hover:shadow-blue-500/10"
>
<div className="space-y-4">
{/* Header */}
<div className="flex items-start justify-between">
<div className="flex-1">
<h3 className="text-xl font-semibold text-white mb-2">
{project.title}
</h3>
<div className="flex flex-wrap gap-2 mb-3">
{project.technologies.map((tech) => (
<span
key={tech}
className="px-2 py-1 bg-blue-500/20 text-blue-400 text-xs rounded-full border border-blue-500/30"
>
{tech}
</span>
))}
</div>
</div>
<div className="flex gap-2">
<a
href={project.demoUrl}
className="p-2 rounded-lg bg-white/10 hover:bg-white/20 transition-colors"
aria-label="Ver demo"
>
<ExternalLink className="w-4 h-4" />
</a>
<a
href={project.githubUrl}
className="p-2 rounded-lg bg-white/10 hover:bg-white/20 transition-colors"
aria-label="Ver código"
>
<Github className="w-4 h-4" />
</a>
</div>
</div>
{/* Description */}
<p className="text-gray-300 leading-relaxed">
{project.description}
</p>
{/* Features */}
<div>
<h4 className="text-sm font-semibold text-blue-400 mb-2">
Funcionalidades:
</h4>
<ul className="space-y-1">
{project.features.map((feature, idx) => (
<li
key={idx}
className="text-sm text-gray-400 flex items-center gap-2"
>
<div className="w-1.5 h-1.5 bg-blue-400 rounded-full" />
{feature}
</li>
))}
</ul>
</div>
{/* Status */}
<div className="pt-2 border-t border-white/10">
<span className="text-xs text-blue-400 font-medium">
{project.status}
</span>
</div>
</div>
</BentoGridItem>
))}
</BentoGrid>
</div>
</section>
);
}