123 lines
5.2 KiB
TypeScript
123 lines
5.2 KiB
TypeScript
|
|
import { motion } from "framer-motion";
|
||
|
|
|
||
|
|
export const TeamCollaborationVector = () => {
|
||
|
|
const teamMembers = [
|
||
|
|
{ role: "Frontend", color: "from-blue-500 to-blue-600", position: { x: 20, y: 20 } },
|
||
|
|
{ role: "Backend", color: "from-green-500 to-green-600", position: { x: 80, y: 20 } },
|
||
|
|
{ role: "Designer", color: "from-purple-500 to-purple-600", position: { x: 50, y: 70 } },
|
||
|
|
{ role: "DevOps", color: "from-orange-500 to-orange-600", position: { x: 20, y: 70 } },
|
||
|
|
{ role: "QA", color: "from-red-500 to-red-600", position: { x: 80, y: 70 } }
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="relative w-full h-96 bg-gradient-to-br from-gray-900/50 to-gray-800/50 rounded-2xl border border-white/10 p-8">
|
||
|
|
{/* Team Members */}
|
||
|
|
{teamMembers.map((member, index) => (
|
||
|
|
<motion.div
|
||
|
|
key={member.role}
|
||
|
|
initial={{ opacity: 0, scale: 0 }}
|
||
|
|
animate={{ opacity: 1, scale: 1 }}
|
||
|
|
transition={{ duration: 0.6, delay: index * 0.2 }}
|
||
|
|
className="absolute"
|
||
|
|
style={{
|
||
|
|
left: `${member.position.x}%`,
|
||
|
|
top: `${member.position.y}%`,
|
||
|
|
transform: 'translate(-50%, -50%)'
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<div className={`w-16 h-16 bg-gradient-to-br ${member.color} rounded-full flex items-center justify-center shadow-lg relative`}>
|
||
|
|
<motion.div
|
||
|
|
animate={{ scale: [1, 1.1, 1] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, delay: index * 0.4 }}
|
||
|
|
className="w-12 h-12 bg-white/20 rounded-full flex items-center justify-center"
|
||
|
|
>
|
||
|
|
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||
|
|
</svg>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Online Status Indicator */}
|
||
|
|
<div className="absolute -bottom-1 -right-1 w-4 h-4 bg-green-400 rounded-full border-2 border-white animate-pulse"></div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Role Label */}
|
||
|
|
<div className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-white text-xs font-manrope whitespace-nowrap bg-gray-800/80 px-2 py-1 rounded">
|
||
|
|
{member.role}
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
|
||
|
|
{/* Collaboration Lines */}
|
||
|
|
<svg className="absolute inset-0 w-full h-full pointer-events-none">
|
||
|
|
<defs>
|
||
|
|
<linearGradient id="collabGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||
|
|
<stop offset="0%" stopColor="#E5195E" stopOpacity="0.6" />
|
||
|
|
<stop offset="50%" stopColor="#3B82F6" stopOpacity="0.4" />
|
||
|
|
<stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.6" />
|
||
|
|
</linearGradient>
|
||
|
|
</defs>
|
||
|
|
|
||
|
|
{/* Dynamic Connection Lines */}
|
||
|
|
{teamMembers.map((member, index) => (
|
||
|
|
teamMembers.slice(index + 1).map((otherMember, otherIndex) => (
|
||
|
|
<motion.line
|
||
|
|
key={`${index}-${otherIndex}`}
|
||
|
|
x1={`${member.position.x}%`}
|
||
|
|
y1={`${member.position.y}%`}
|
||
|
|
x2={`${otherMember.position.x}%`}
|
||
|
|
y2={`${otherMember.position.y}%`}
|
||
|
|
stroke="url(#collabGradient)"
|
||
|
|
strokeWidth="2"
|
||
|
|
strokeDasharray="4,4"
|
||
|
|
initial={{ pathLength: 0, opacity: 0 }}
|
||
|
|
animate={{ pathLength: 1, opacity: 0.6 }}
|
||
|
|
transition={{
|
||
|
|
duration: 1.5,
|
||
|
|
delay: (index + otherIndex) * 0.3 + 1,
|
||
|
|
repeat: Infinity,
|
||
|
|
repeatType: "reverse",
|
||
|
|
repeatDelay: 2
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
))
|
||
|
|
))}
|
||
|
|
</svg>
|
||
|
|
|
||
|
|
{/* Central Project Hub */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, scale: 0 }}
|
||
|
|
animate={{ opacity: 1, scale: 1 }}
|
||
|
|
transition={{ duration: 0.8, delay: 1 }}
|
||
|
|
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-20 h-20 bg-gradient-to-br from-accent to-purple-600 rounded-full flex items-center justify-center shadow-xl"
|
||
|
|
>
|
||
|
|
<motion.div
|
||
|
|
animate={{ rotate: 360 }}
|
||
|
|
transition={{ duration: 10, repeat: Infinity, ease: "linear" }}
|
||
|
|
>
|
||
|
|
<svg className="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
|
|
</svg>
|
||
|
|
</motion.div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Floating Code/Design Elements */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 1.5 }}
|
||
|
|
className="absolute top-4 right-4 space-y-2"
|
||
|
|
>
|
||
|
|
{['React', 'Design', 'API'].map((tech, index) => (
|
||
|
|
<motion.div
|
||
|
|
key={tech}
|
||
|
|
animate={{ x: [0, 5, 0] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, delay: index * 0.2 }}
|
||
|
|
className="px-3 py-1 bg-white/10 border border-white/20 rounded-full text-white text-xs font-manrope backdrop-blur-sm"
|
||
|
|
>
|
||
|
|
{tech}
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|