import { useRef, useState, useEffect } from 'react' import { motion } from 'framer-motion' import type { Skill } from '../types' import { calculateSkillOffset } from '../lib/utils' const GAUGE_RADIUS = 34 const GAUGE_CIRCUMFERENCE = 2 * Math.PI * GAUGE_RADIUS interface SkillGaugeProps { skill: Skill delay: number isVisible: boolean } function SkillGauge({ skill, delay, isVisible }: SkillGaugeProps) { const [animated, setAnimated] = useState(false) const strokeColor = skill.color === 'coral' ? '#FF6B6B' : '#00897B' const hoverBg = skill.color === 'coral' ? 'hover:bg-coral-light' : 'hover:bg-teal-light' const targetOffset = calculateSkillOffset(skill.level, GAUGE_RADIUS) useEffect(() => { if (isVisible && !animated) { const timer = setTimeout(() => setAnimated(true), delay) return () => clearTimeout(timer) } }, [isVisible, animated, delay]) return ( {skill.level}% {skill.name} {skill.category} ) } interface SkillCategoryProps { label: string skills: Skill[] isVisible: boolean baseDelay: number } function SkillCategory({ label, skills, isVisible, baseDelay }: SkillCategoryProps) { return (

{label}

{skills.map((skill, index) => ( ))}
) } const skillsData: Skill[] = [ { name: 'Python', level: 90, category: 'Technical', color: 'teal' }, { name: 'SQL', level: 88, category: 'Technical', color: 'teal' }, { name: 'Power BI', level: 92, category: 'Technical', color: 'teal' }, { name: 'JS / TS', level: 70, category: 'Technical', color: 'teal' }, { name: 'Data Analysis', level: 95, category: 'Technical', color: 'teal' }, { name: 'Dashboard Dev', level: 88, category: 'Technical', color: 'teal' }, { name: 'Algorithm Design', level: 82, category: 'Technical', color: 'teal' }, { name: 'Data Pipelines', level: 80, category: 'Technical', color: 'teal' }, { name: 'Medicines Optimisation', level: 95, category: 'Clinical', color: 'coral' }, { name: 'Pop. Health Analytics', level: 90, category: 'Clinical', color: 'coral' }, { name: 'NICE TA', level: 85, category: 'Clinical', color: 'coral' }, { name: 'Health Economics', level: 80, category: 'Clinical', color: 'coral' }, { name: 'Clinical Pathways', level: 82, category: 'Clinical', color: 'coral' }, { name: 'CD Assurance', level: 88, category: 'Clinical', color: 'coral' }, { name: 'Budget Mgmt', level: 90, category: 'Strategic', color: 'teal' }, { name: 'Stakeholder Engagement', level: 88, category: 'Strategic', color: 'teal' }, { name: 'Pharma Negotiation', level: 85, category: 'Strategic', color: 'teal' }, { name: 'Team Development', level: 82, category: 'Strategic', color: 'teal' }, ] export function Skills() { const sectionRef = useRef(null) const [isVisible, setIsVisible] = useState(false) useEffect(() => { const element = sectionRef.current if (!element) return const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setIsVisible(true) observer.unobserve(element) } }, { threshold: 0.15, rootMargin: '0px' } ) observer.observe(element) return () => observer.disconnect() }, []) const technicalSkills = skillsData.filter(s => s.category === 'Technical') const clinicalSkills = skillsData.filter(s => s.category === 'Clinical') const strategicSkills = skillsData.filter(s => s.category === 'Strategic') return (
Skills & Expertise
) }