This commit initializes the project with a basic Next.js setup, including: - Integration of `tailwindcss` and `tw-animate-css` for styling. - Definition of a comprehensive color palette using CSS variables for both light and dark themes, supporting a theming system. - Implementation of a custom `aurora` keyframe animation. - Configuration of global CSS styles for `border` and `body` elements. - Setup of `next.config.ts` with image optimization, performance enhancements, and security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy). - Update of `package.json` to include new dependencies for UI components (`class-variance-authority`, `clsx`, `lucide-react`, `motion`, `tailwind-merge`, `tailwindcss-animate`) and development tools (`@biomejs/biome`, `@tailwindcss/postcss`, `tw-animate-css`). - Refinement of `app/layout.tsx` to include comprehensive metadata for SEO (title, description, keywords, authors, Open Graph, Twitter cards, robots), preconnect/dns-prefetch links for external resources, favicon, manifest, and mobile app meta tags. - Restructuring of `app/page.tsx` to use dynamic imports for various sections (Hero, About, Skills, Experience, Projects, Contact, WorkModalities) to improve performance, and integration of `Squares` component for background effects. This foundational commit prepares the application for further development by establishing a robust and performant base.
135 lines
4.7 KiB
TypeScript
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">
|
|
<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>
|
|
);
|
|
}
|