import React, { useState, useEffect } from 'react'; import { motion, useMotionValue, useSpring } from 'framer-motion'; // --- mock data --- const PROJECTS = [ { id: 1, title: "TaskFlow API", category: "Backend", description: "A high-throughput microservice handling real-time project syncing and background workers.", metrics: { stars: 142, uptime: "99.98%", commits: "412" }, tags: ["Node.js", "TypeScript", "Redis", "Docker"], repo: "https://github.com/jeanlucponsard/taskflow", demo: "https://jeanlucponsard.dev/taskflow" }, { id: 2, title: "DevMetrics Dashboard", category: "Frontend", description: "An interactive telemetry UI rendering real-time system performance and database health.", metrics: { stars: 89, uptime: "100%", commits: "185" }, tags: ["Next.js", "Tailwind", "Framer Motion", "Recharts"], repo: "https://github.com/jeanlucponsard/devmetrics", demo: "https://jeanlucponsard.dev/metrics" }, { id: 3, title: "Sentinel Auth", category: "Security", description: "A lightweight, zero-dependency OAuth2 provider featuring biometric passkey support.", metrics: { stars: 310, uptime: "99.99%", commits: "290" }, tags: ["Go", "WebAuthn", "SQLite", "Crypto"], repo: "https://github.com/jeanlucponsard/sentinel", demo: "https://jeanlucponsard.dev/sentinel" } ]; export default function ProjectPanel() { const [filter, setFilter] = useState("All"); const [hoveredCard, setHoveredCard] = useState(null); const [cursorText, setCursorText] = useState(""); // Custom Cursor Logic const cursorX = useMotionValue(-100); const cursorY = useMotionValue(-100); const springConfig = { damping: 25, stiffness: 250 }; const cursorXSpring = useSpring(cursorX, springConfig); const cursorYSpring = useSpring(cursorY, springConfig); useEffect(() => { const moveCursor = (e) => { cursorX.set(e.clientX - 16); cursorY.set(e.clientY - 16); }; window.addEventListener("mousemove", moveCursor); return () => window.removeEventListener("mousemove", moveCursor); }, [cursorX, cursorY]); const filteredProjects = filter === "All" ? PROJECTS : PROJECTS.filter(p => p.category === filter); return (
// PORTFOLIO.PROJECTS
{project.description}
{/* 3. Metrics Widget Panel */}Stars
{project.metrics.stars}
Uptime
{project.metrics.uptime}
Commits
{project.metrics.commits}