Enhance the About page with new story sections detailing personal journey and core values, including icons and structured content for better user engagement and self-presentation.
142 lines
4.7 KiB
TypeScript
142 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "motion/react";
|
|
import { MagicCard } from "@/components/magicui/magic-card";
|
|
import {
|
|
Code,
|
|
Database,
|
|
Cloud,
|
|
Cpu,
|
|
Smartphone,
|
|
Zap,
|
|
GitBranch,
|
|
TestTube,
|
|
} from "lucide-react";
|
|
import { usePortfolioData } from "@/lib/usePortfolioData";
|
|
|
|
// Mapa de ícones para as categorias
|
|
const iconMap = {
|
|
Code: Code,
|
|
Database: Database,
|
|
Cloud: Cloud,
|
|
Cpu: Cpu,
|
|
Smartphone: Smartphone,
|
|
Zap: Zap,
|
|
GitBranch: GitBranch,
|
|
TestTube: TestTube,
|
|
};
|
|
|
|
// Mapa de cores para garantir que o Tailwind inclua as classes no bundle
|
|
const colorMap = {
|
|
"text-blue-440": "bg-blue-400",
|
|
"text-blue-400": "bg-blue-400",
|
|
"text-green-400": "bg-blue-400",
|
|
"text-purple-400": "bg-blue-400",
|
|
"text-red-400": "bg-blue-400",
|
|
"text-yellow-400": "bg-blue-400",
|
|
"text-pink-400": "bg-blue-400",
|
|
"text-indigo-400": "bg-blue-400",
|
|
};
|
|
|
|
export default function Skills() {
|
|
const { data, loading, error } = usePortfolioData();
|
|
|
|
if (loading) {
|
|
return (
|
|
<section id="skills" 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="skills" className="py-20 px-4">
|
|
<div className="max-w-6xl mx-auto text-center">
|
|
<p className="text-red-400">Erro ao carregar dados de habilidades.</p>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
const skillCategories = data.skills.technical;
|
|
|
|
return (
|
|
<section id="skills" 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"
|
|
>
|
|
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-cyan-400/10 to-blue-500/10 px-6 py-3 rounded-full mb-6 border border-cyan-400/20">
|
|
<div className="w-2 h-2 bg-cyan-400 rounded-full animate-pulse"></div>
|
|
<span className="text-sm font-medium text-cyan-300">
|
|
Tecnologias Dominadas
|
|
</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6 bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
|
|
Habilidades Técnicas
|
|
</h2>
|
|
<p className="text-xl text-gray-300 max-w-2xl mx-auto">
|
|
Tecnologias e ferramentas que utilizo para criar soluções inovadoras
|
|
</p>
|
|
</motion.div>
|
|
|
|
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
{skillCategories.map((category, index) => {
|
|
const IconComponent =
|
|
iconMap[category.icon as keyof typeof iconMap] || Code;
|
|
return (
|
|
<motion.div
|
|
key={category.category}
|
|
initial={{ opacity: 0, y: 30 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.8, delay: index * 0.1 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<div className="p-6 space-y-4 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl hover:border-cyan-500/30 transition-all duration-300 hover:scale-105">
|
|
{/* Header */}
|
|
<div className="flex items-center gap-3">
|
|
<div className={`p-3 rounded-lg ${category.bgColor}`}>
|
|
<IconComponent className={`w-6 h-6 ${category.color}`} />
|
|
</div>
|
|
<h3 className="text-xl font-semibold">
|
|
{category.category}
|
|
</h3>
|
|
</div>
|
|
|
|
{/* Skills List */}
|
|
<div className="space-y-2">
|
|
{category.skills.map((skill, skillIndex) => (
|
|
<div
|
|
key={skillIndex}
|
|
className="flex items-center gap-2 text-gray-300"
|
|
>
|
|
<div
|
|
className={`w-2 h-2 rounded-full ${
|
|
colorMap[category.color as keyof typeof colorMap] ||
|
|
"bg-gray-400"
|
|
}`}
|
|
/>
|
|
<span className="text-sm">{skill}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|