Files
xeewy.be/src/components/Skills.tsx

199 lines
6.3 KiB
TypeScript

import { motion } from 'framer-motion';
import { Code, Database, Smartphone, Globe, Server, Wrench } from 'lucide-react';
import { useLanguage } from '../contexts/LanguageContext';
const Skills = () => {
const { t } = useLanguage();
const skillCategories = [
{
id: 'mobile',
icon: <Smartphone size={32} />,
title: t('skills.category.mobile'),
color: "#4FC3F7",
skills: [
{ name: "Dart", level: 85, color: "#0175C2" },
{ name: "Flutter", level: 80, color: "#02569B" }
]
},
{
id: 'frontend',
icon: <Globe size={32} />,
title: t('skills.category.frontend'),
color: "#42A5F5",
skills: [
{ name: "React", level: 75, color: "#61DAFB" },
{ name: "TypeScript", level: 70, color: "#3178C6" },
{ name: "JavaScript", level: 80, color: "#F7DF1E" }
]
},
{
id: 'backend',
icon: <Server size={32} />,
title: t('skills.category.backend'),
color: "#66BB6A",
skills: [
{ name: "Java", level: 75, color: "#ED8B00" },
{ name: "C#", level: 65, color: "#239120" }
]
},
{
id: 'tools',
icon: <Wrench size={32} />,
title: t('skills.category.tools'),
color: "#AB47BC",
skills: [
{ name: "Git", level: 70, color: "#F05032" },
{ name: "VS Code", level: 90, color: "#007ACC" },
{ name: "Android Studio", level: 75, color: "#3DDC84" }
]
}
];
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
delayChildren: 0.3
}
}
};
const categoryVariants = {
hidden: { opacity: 0, y: 50 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.6,
ease: [0.25, 0.1, 0.25, 1] as const
}
}
};
return (
<section id="skills" className="skills">
<div className="container">
<motion.div
key="skills-header"
className="section-header"
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
>
<h2 className="section-title">{t('skills.title')}</h2>
<p className="section-subtitle">
{t('skills.subtitle')}
</p>
</motion.div>
<motion.div
key="skills-grid"
className="skills-grid"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{skillCategories.map((category, categoryIndex) => (
<motion.div
key={category.id}
className="skill-category"
variants={categoryVariants}
whileHover={{
scale: 1.02,
y: -5,
transition: { duration: 0.3 }
}}
>
<div className="category-header">
<div
className="category-icon"
style={{ backgroundColor: `${category.color}20`, color: category.color }}
>
{category.icon}
</div>
<h3 className="category-title">{category.title}</h3>
</div>
<div className="skills-list">
{category.skills.map((skill, skillIndex) => (
<motion.div
key={skill.name}
className="skill-item"
initial={{ opacity: 0, x: -30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{
duration: 0.5,
delay: (categoryIndex * 0.2) + (skillIndex * 0.1)
}}
viewport={{ once: true }}
>
<div className="skill-header">
<span className="skill-name">{skill.name}</span>
<span className="skill-percentage">{skill.level}%</span>
</div>
<div className="skill-bar">
<motion.div
className="skill-progress"
style={{ backgroundColor: skill.color }}
initial={{ width: 0 }}
whileInView={{ width: `${skill.level}%` }}
transition={{
duration: 1.5,
delay: (categoryIndex * 0.2) + (skillIndex * 0.1) + 0.5,
ease: [0.25, 0.1, 0.25, 1] as const
}}
viewport={{ once: true }}
/>
</div>
</motion.div>
))}
</div>
</motion.div>
))}
</motion.div>
{/* Section des soft skills */}
<motion.div
className="soft-skills"
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.3 }}
viewport={{ once: true }}
>
<h3 className="soft-skills-title">{t('skills.otherSkills')}</h3>
<div className="soft-skills-grid">
{[
{ name: t('skills.problemSolving'), icon: <Wrench size={20} /> },
{ name: t('skills.teamwork'), icon: <Code size={20} /> },
{ name: t('skills.continuousLearning'), icon: <Database size={20} /> },
{ name: t('skills.communication'), icon: <Globe size={20} /> }
].map((softSkill, index) => (
<motion.div
key={softSkill.name}
className="soft-skill-tag"
initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
whileHover={{
scale: 1.05,
transition: { duration: 0.2 }
}}
viewport={{ once: true }}
>
{softSkill.icon}
<span>{softSkill.name}</span>
</motion.div>
))}
</div>
</motion.div>
</div>
</section>
);
};
export default Skills;