feat(about, contact, header, hero, skills): enhance component structure and navigation

- Added section IDs to About, Contact, and Hero components for improved navigation and accessibility.
- Refactored Header component to utilize a structured navigation array, enhancing maintainability and responsiveness.
- Updated Skills component to improve type handling and visual consistency, including a loading state and error handling.
- Adjusted styling and animations across components for a smoother user experience and better visual appeal.
This commit is contained in:
Evandro Fonseca Junior committed 2026-01-12 16:12:33 -03:00
1 parent 8987d06eb4
commit 7c9cada65f
6 files changed
+162 -182

No files matched your search

+24 -16
View File
@@ -1,7 +1,7 @@
"use client";
import React, { useMemo } from "react";
import { motion } from "motion/react";
import React from "react";
import { motion } from "framer-motion"; // Ajustado para o padrão estável
import { MagicCard } from "@/components/magicui/magic-card";
import {
Code, Database, Cloud, Cpu, Smartphone,
@@ -9,19 +9,29 @@ import {
} from "lucide-react";
import { usePortfolioData } from "@/lib/usePortfolioData";
// --- RESOLUÇÃO DE TIPAGEM (Wrapper) ---
// Estendemos a interface original para aceitar as props de gradiente que a lib pode ter omitido nos tipos
interface FixedMagicCardProps extends React.ComponentProps<typeof MagicCard> {
gradientColor?: string;
gradientSize?: number;
gradientOpacity?: number;
}
const FixedMagicCard = (props: FixedMagicCardProps) => {
// @ts-ignore - Forçamos o cast para o componente original aceitar as props em runtime
return <MagicCard {...props} />;
};
const ICON_MAP: Record<string, React.ElementType> = {
Code, Database, Cloud, Cpu, Smartphone, Zap, GitBranch, TestTube, Terminal
Code, Database, Cloud, Cpu, Smartphone, Zap, GitBranch, TestTube, Terminal, Layers
};
// Refinamento do Pareto: Cores baseadas em variáveis CSS para evitar quebras no Tailwind
const getCategoryStyles = (color: string) => {
const base = color.replace("text-", "");
return {
icon: color,
bg: `bg-${base}/10`,
// Removido o hover:border daqui para evitar conflitos de transição
border: `border-slate-800/50`,
glow: `rgba(var(--${base}-rgb, 59, 130, 246), 0.15)` // Fallback para azul
};
};
@@ -35,7 +45,7 @@ export default function Skills() {
<section id="skills" className="relative py-32 px-6 bg-[#030712] overflow-hidden">
<div className="max-w-7xl mx-auto relative z-10">
{/* Header Header */}
{/* Header Seção */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@@ -66,7 +76,6 @@ export default function Skills() {
key={category.category}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
// Previne que o card suma se o scroll for rápido
viewport={{ once: true, amount: 0.2 }}
transition={{
duration: 0.5,
@@ -74,9 +83,8 @@ export default function Skills() {
ease: "easeOut"
}}
>
<MagicCard
className="group p-8 flex flex-col h-full bg-slate-900/50 border-slate-800 transition-colors duration-300"
// DEFINIÇÃO EXPLÍCITA DO BRILHO (Corrige o glitch)
<FixedMagicCard
className="group p-8 flex flex-col h-full bg-slate-900/50 border-slate-800 transition-colors duration-300 cursor-default"
gradientColor="#262626"
gradientSize={250}
gradientOpacity={0.4}
@@ -104,7 +112,7 @@ export default function Skills() {
</span>
))}
</div>
</MagicCard>
</FixedMagicCard>
</motion.div>
);
})}
@@ -114,19 +122,19 @@ export default function Skills() {
);
}
// --- Componentes de Suporte (Clean Code) ---
// --- Componentes de Suporte (Manter no mesmo arquivo para contexto ou mover para /components) ---
function LoadingState() {
return (
<div className="py-32 flex flex-col items-center justify-center space-y-4">
<div className="py-32 flex flex-col items-center justify-center space-y-4 bg-[#030712]">
<div className="w-12 h-12 border-4 border-blue-500/20 border-t-blue-500 rounded-full animate-spin" />
<span className="text-slate-500 font-mono text-sm animate-pulse">Initializing Systems...</span>
<span className="text-slate-500 font-mono text-sm animate-pulse uppercase tracking-tighter">Initializing Systems...</span>
</div>
);
}
function ErrorState() {
return (
<div className="py-32 text-center text-red-400 font-mono">
<div className="py-32 text-center text-red-400 font-mono bg-[#030712]">
[FATAL_ERROR]: Failed to synchronize portfolio data.
</div>
);