237 lines
9.3 KiB
TypeScript
237 lines
9.3 KiB
TypeScript
|
|
import { motion } from "framer-motion";
|
||
|
|
|
||
|
|
export const FullStackVector = () => {
|
||
|
|
return (
|
||
|
|
<div className="relative w-full h-96 flex items-center justify-center overflow-hidden font-manrope">
|
||
|
|
{/* Subtle Background */}
|
||
|
|
<div className="absolute inset-0 opacity-5">
|
||
|
|
<svg className="w-full h-full" viewBox="0 0 400 400" fill="none">
|
||
|
|
<defs>
|
||
|
|
<radialGradient id="bgGradient" cx="50%" cy="50%" r="30%">
|
||
|
|
<stop offset="0%" stopColor="#E5195E" stopOpacity="0.04" />
|
||
|
|
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.02" />
|
||
|
|
</radialGradient>
|
||
|
|
</defs>
|
||
|
|
<circle cx="200" cy="200" r="80" fill="url(#bgGradient)" />
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="relative z-20 flex items-center justify-center space-x-12">
|
||
|
|
{/* Database Component */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, x: -40 }}
|
||
|
|
animate={{ opacity: 1, x: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||
|
|
className="flex flex-col items-center"
|
||
|
|
>
|
||
|
|
{/* Database Icon */}
|
||
|
|
<div className="relative">
|
||
|
|
<motion.div
|
||
|
|
animate={{ y: [0, -4, 0] }}
|
||
|
|
transition={{ duration: 3, repeat: Infinity }}
|
||
|
|
className="w-16 h-20 bg-gradient-to-b from-blue-600 to-blue-800 rounded-lg flex flex-col justify-between p-2 shadow-lg border border-blue-500/20"
|
||
|
|
>
|
||
|
|
{/* Database layers */}
|
||
|
|
<div className="w-full h-2 bg-blue-400/30 rounded-full"></div>
|
||
|
|
<div className="w-full h-2 bg-blue-400/30 rounded-full"></div>
|
||
|
|
<div className="w-full h-2 bg-blue-400/30 rounded-full"></div>
|
||
|
|
<div className="w-full h-2 bg-blue-400/30 rounded-full"></div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Database Label */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ duration: 0.5, delay: 0.8 }}
|
||
|
|
className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-xs text-white font-manrope whitespace-nowrap"
|
||
|
|
>
|
||
|
|
Database
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Server Stack */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 30 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 0.4 }}
|
||
|
|
className="flex flex-col items-center"
|
||
|
|
>
|
||
|
|
{/* Server Stack */}
|
||
|
|
<div className="relative">
|
||
|
|
<div className="flex flex-col space-y-1">
|
||
|
|
{Array.from({ length: 4 }).map((_, i) => (
|
||
|
|
<motion.div
|
||
|
|
key={i}
|
||
|
|
initial={{ opacity: 0, scale: 0.8 }}
|
||
|
|
animate={{ opacity: 1, scale: 1 }}
|
||
|
|
transition={{ duration: 0.4, delay: 0.6 + i * 0.1 }}
|
||
|
|
className="relative"
|
||
|
|
>
|
||
|
|
<div className="w-20 h-6 bg-gradient-to-r from-green-600 to-green-700 rounded flex items-center justify-between px-2 border border-green-500/20">
|
||
|
|
{/* Server indicator */}
|
||
|
|
<motion.div
|
||
|
|
animate={{ scale: [1, 1.2, 1] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, delay: i * 0.5 }}
|
||
|
|
className="w-2 h-2 bg-green-400 rounded-full"
|
||
|
|
></motion.div>
|
||
|
|
|
||
|
|
{/* Server number */}
|
||
|
|
<span className="text-xs text-white font-manrope">#{i + 1}</span>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* API Label */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ duration: 0.5, delay: 1.2 }}
|
||
|
|
className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-xs text-white font-manrope whitespace-nowrap"
|
||
|
|
>
|
||
|
|
API Server
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Gateway Component */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, x: 40 }}
|
||
|
|
animate={{ opacity: 1, x: 0 }}
|
||
|
|
transition={{ duration: 0.8, delay: 0.6 }}
|
||
|
|
className="flex flex-col items-center"
|
||
|
|
>
|
||
|
|
{/* Gateway Icon */}
|
||
|
|
<div className="relative">
|
||
|
|
<motion.div
|
||
|
|
animate={{ rotate: [0, 360] }}
|
||
|
|
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||
|
|
className="w-16 h-16 bg-gradient-to-br from-purple-600 to-purple-800 rounded-xl flex items-center justify-center shadow-lg border border-purple-500/20"
|
||
|
|
>
|
||
|
|
<motion.div
|
||
|
|
animate={{ scale: [1, 1.1, 1] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity }}
|
||
|
|
className="text-white text-lg font-manrope"
|
||
|
|
>
|
||
|
|
⚡
|
||
|
|
</motion.div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Gateway Label */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ duration: 0.5, delay: 1.0 }}
|
||
|
|
className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-xs text-white font-manrope whitespace-nowrap"
|
||
|
|
>
|
||
|
|
Gateway
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Connection Lines */}
|
||
|
|
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-20 z-15">
|
||
|
|
<defs>
|
||
|
|
<linearGradient id="connectionGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||
|
|
<stop offset="0%" stopColor="#3B82F6" stopOpacity="0.4" />
|
||
|
|
<stop offset="50%" stopColor="#E5195E" stopOpacity="0.3" />
|
||
|
|
<stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.4" />
|
||
|
|
</linearGradient>
|
||
|
|
</defs>
|
||
|
|
|
||
|
|
<motion.line
|
||
|
|
x1="35%" y1="50%" x2="60%" y2="50%"
|
||
|
|
stroke="url(#connectionGradient)"
|
||
|
|
strokeWidth="2"
|
||
|
|
strokeDasharray="3,3"
|
||
|
|
initial={{ pathLength: 0 }}
|
||
|
|
animate={{ pathLength: 1 }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse" }}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<motion.line
|
||
|
|
x1="60%" y1="50%" x2="85%" y2="50%"
|
||
|
|
stroke="url(#connectionGradient)"
|
||
|
|
strokeWidth="2"
|
||
|
|
strokeDasharray="3,3"
|
||
|
|
initial={{ pathLength: 0 }}
|
||
|
|
animate={{ pathLength: 1 }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse", delay: 0.5 }}
|
||
|
|
/>
|
||
|
|
</svg>
|
||
|
|
|
||
|
|
{/* Performance Metrics */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.6, delay: 1.4 }}
|
||
|
|
className="absolute top-8 right-8 z-25"
|
||
|
|
>
|
||
|
|
<div className="bg-black/30 backdrop-blur-sm rounded-lg p-3 border border-white/10">
|
||
|
|
<div className="space-y-2">
|
||
|
|
<div className="flex items-center space-x-2">
|
||
|
|
<motion.div
|
||
|
|
animate={{ scale: [1, 1.2, 1] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity }}
|
||
|
|
className="w-2 h-2 bg-green-400 rounded-full"
|
||
|
|
></motion.div>
|
||
|
|
<span className="text-green-400 text-xs font-manrope">99.9% Uptime</span>
|
||
|
|
</div>
|
||
|
|
<div className="flex items-center space-x-2">
|
||
|
|
<motion.div
|
||
|
|
animate={{ scale: [1, 1.2, 1] }}
|
||
|
|
transition={{ duration: 2, repeat: Infinity, delay: 0.5 }}
|
||
|
|
className="w-2 h-2 bg-blue-400 rounded-full"
|
||
|
|
></motion.div>
|
||
|
|
<span className="text-blue-400 text-xs font-manrope">50ms Response</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Technology Stack */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ duration: 0.6, delay: 1.6 }}
|
||
|
|
className="absolute bottom-8 left-8 z-25"
|
||
|
|
>
|
||
|
|
<div className="bg-black/30 backdrop-blur-sm rounded-lg p-2 border border-white/10">
|
||
|
|
<div className="flex space-x-2">
|
||
|
|
{[
|
||
|
|
{ name: "Node.js", color: "bg-green-600" },
|
||
|
|
{ name: "SQL", color: "bg-blue-600" },
|
||
|
|
{ name: "Redis", color: "bg-red-600" }
|
||
|
|
].map((tech, index) => (
|
||
|
|
<motion.div
|
||
|
|
key={tech.name}
|
||
|
|
initial={{ scale: 0 }}
|
||
|
|
animate={{ scale: 1 }}
|
||
|
|
transition={{ duration: 0.3, delay: 1.8 + index * 0.1 }}
|
||
|
|
className={`px-2 py-1 ${tech.color}/20 border border-white/10 rounded text-xs text-white font-manrope`}
|
||
|
|
>
|
||
|
|
{tech.name}
|
||
|
|
</motion.div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
{/* Data Flow Indicator */}
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0, scale: 0 }}
|
||
|
|
animate={{ opacity: 1, scale: 1 }}
|
||
|
|
transition={{ duration: 0.5, delay: 2 }}
|
||
|
|
className="absolute bottom-8 right-8 z-25"
|
||
|
|
>
|
||
|
|
<motion.div
|
||
|
|
animate={{ rotate: [0, 360] }}
|
||
|
|
transition={{ duration: 8, repeat: Infinity, ease: "linear" }}
|
||
|
|
className="w-8 h-8 border-2 border-gray-600 border-t-accent rounded-full"
|
||
|
|
></motion.div>
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|