"use client"; import { useState, useEffect } from "react"; import { useTranslations } from "next-intl"; const techItems = [ // ================= ORBIT 1 ================= { key: "react", orbit: 1, startAngle: 0, icon: ( ), }, { key: "nextjs", orbit: 1, startAngle: 180, icon: ( ), }, // ================= ORBIT 2 ================= { key: "postgresql", orbit: 2, startAngle: 90, icon: ( ), }, { key: "mongodb", orbit: 2, startAngle: 270, icon: ( ), }, // ================= ORBIT 3 ================= { key: "docker", orbit: 3, startAngle: 45, icon: ( ), }, { key: "django", orbit: 3, startAngle: 225, icon: ( dj ), }, // ================= ORBIT 4 ================= { key: "nestjs", orbit: 4, startAngle: 135, icon: ( ), }, { key: "typescript", orbit: 4, startAngle: 315, icon: ( ), }, ]; export default function TechStack() { const t = useTranslations("software.techStack"); const [selected, setSelected] = useState(techItems[0]); const [dimensions, setDimensions] = useState({ size: 800, center: 400, baseRadius: 120, gap: 70, }); useEffect(() => { const updateDimensions = () => { const width = window.innerWidth; if (width < 640) { setDimensions({ size: 400, center: 200, baseRadius: 60, gap: 35 }); } else if (width < 1024) { setDimensions({ size: 500, center: 250, baseRadius: 80, gap: 45 }); } else { setDimensions({ size: 800, center: 400, baseRadius: 120, gap: 70 }); } }; updateDimensions(); window.addEventListener("resize", updateDimensions); return () => window.removeEventListener("resize", updateDimensions); }, []); const { size, center, baseRadius, gap } = dimensions; return ( {t("title")} {t("subtitle")} {/* Orbital Tech System */} {/* Sun (Center) */} {t("center")} {/* Orbits (Rings 1 to 4) */} {[1, 2, 3, 4].map((orbit) => { const radius = baseRadius + orbit * gap; return ( ); })} {/* Orbiting Items */} {techItems.map((tech, i) => { const radius = baseRadius + tech.orbit * gap; const speed = 25 + tech.orbit * 10; const angleRad = (tech.startAngle * Math.PI) / 180; const x = center + radius * Math.cos(angleRad); const y = center + radius * Math.sin(angleRad); return ( setSelected(tech)} className={`pointer-events-auto cursor-pointer -translate-x-1/2 -translate-y-1/2 w-10 h-10 sm:w-12 sm:h-12 lg:w-14 lg:h-14 rounded-full flex items-center justify-center transition-all z-20 bg-background ${ selected.key === tech.key ? "border-2 border-accent shadow-[0_0_15px_rgba(249,115,22,0.5)] sm:shadow-[0_0_20px_rgba(249,115,22,0.5)] scale-110" : "border border-border hover:border-accent/50 hover:scale-110" } `} style={{ animation: `counter-rotate ${speed}s linear infinite`, }} > {tech.icon} ); })} {/* Information Card */} {selected.icon} {t(`items.${selected.key}.name`)} {t(`items.${selected.key}.description`)} ); }
{t("subtitle")}
{t(`items.${selected.key}.description`)}