working on hire talent banner
This commit is contained in:
@@ -14,6 +14,7 @@ import { Input } from "./ui/input";
|
||||
import BlackLogo14 from "../assets/BlackLogo14";
|
||||
import { navigateTo } from "../App";
|
||||
import { useState } from "react";
|
||||
import GlobalOffices from "./GlobalOffices";
|
||||
|
||||
const footerNavigation = {
|
||||
Explore: [
|
||||
@@ -269,110 +270,109 @@ const NewsletterSection = () => {
|
||||
|
||||
export const Footer = () => {
|
||||
return (
|
||||
<footer className="relative bg-[#0E0E0E] border-t border-white/10 overflow-hidden">
|
||||
<GridPattern strokeDasharray="4 2" />
|
||||
<>
|
||||
<GlobalOffices />
|
||||
<footer className="relative bg-[#0E0E0E] border-t border-white/10 overflow-hidden">
|
||||
<GridPattern strokeDasharray="4 2" />
|
||||
|
||||
<div className="relative z-10">
|
||||
{/* Main Footer Content */}
|
||||
<div className="container mx-auto px-6 lg:px-8 py-16">
|
||||
<div className="grid lg:grid-cols-7 gap-12">
|
||||
{/* Company Info */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="lg:col-span-2 space-y-6"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<div className="w-12 h-12">
|
||||
<BlackLogo14 />
|
||||
<div className="relative z-10">
|
||||
{/* Main Footer Content */}
|
||||
<div className="container mx-auto px-6 lg:px-8 py-16">
|
||||
<div className="grid lg:grid-cols-7 gap-12">
|
||||
{/* Company Info */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="lg:col-span-2 space-y-6"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<div className="w-12 h-12">
|
||||
<BlackLogo14 />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-[#CCCCCC] leading-relaxed max-w-md">
|
||||
Web Development Institute - Transforming ideas
|
||||
into scalable digital products. 25+ years of
|
||||
industry expertise, serving founders and CTOs
|
||||
across 15+ countries.
|
||||
</p>
|
||||
<p className="text-[#CCCCCC] leading-relaxed max-w-md">
|
||||
Website Developers India Pvt. Ltd. - Transforming ideas into scalable digital products. 25+ years of industry expertise, serving founders and CTOs across 15+ countries.
|
||||
</p>
|
||||
|
||||
{/* India Office Contact Information */}
|
||||
<div className="space-y-4">
|
||||
<h5 className="font-semibold text-white text-sm tracking-wide uppercase">
|
||||
India Office
|
||||
</h5>
|
||||
<div className="space-y-3">
|
||||
{contactInfo.map((contact) => {
|
||||
const Icon = contact.icon;
|
||||
{/* India Office Contact Information */}
|
||||
<div className="space-y-4">
|
||||
<h5 className="font-semibold text-white text-sm tracking-wide uppercase">
|
||||
India Office
|
||||
</h5>
|
||||
<div className="space-y-3">
|
||||
{contactInfo.map((contact) => {
|
||||
const Icon = contact.icon;
|
||||
return (
|
||||
<a
|
||||
key={contact.label}
|
||||
href={contact.url}
|
||||
className="flex items-start gap-3 text-[#CCCCCC] hover:text-white transition-colors duration-200"
|
||||
>
|
||||
<Icon className="w-4 h-4 text-[#E5195E] mt-0.5 flex-shrink-0" />
|
||||
<span className="text-sm leading-relaxed">
|
||||
{contact.label}
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Social Links */}
|
||||
<div className="flex gap-4 pt-4">
|
||||
{socialLinks.map((social) => {
|
||||
const Icon = social.icon;
|
||||
return (
|
||||
<a
|
||||
key={contact.label}
|
||||
href={contact.url}
|
||||
className="flex items-start gap-3 text-[#CCCCCC] hover:text-white transition-colors duration-200"
|
||||
key={social.name}
|
||||
href={social.url}
|
||||
className="w-10 h-10 bg-white/5 rounded-lg flex items-center justify-center text-[#CCCCCC] hover:text-white hover:bg-[#E5195E]/20 transition-all duration-200"
|
||||
aria-label={social.name}
|
||||
>
|
||||
<Icon className="w-4 h-4 text-[#E5195E] mt-0.5 flex-shrink-0" />
|
||||
<span className="text-sm leading-relaxed">
|
||||
{contact.label}
|
||||
</span>
|
||||
<Icon className="w-4 h-4" />
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Social Links */}
|
||||
<div className="flex gap-4 pt-4">
|
||||
{socialLinks.map((social) => {
|
||||
const Icon = social.icon;
|
||||
return (
|
||||
<a
|
||||
key={social.name}
|
||||
href={social.url}
|
||||
className="w-10 h-10 bg-white/5 rounded-lg flex items-center justify-center text-[#CCCCCC] hover:text-white hover:bg-[#E5195E]/20 transition-all duration-200"
|
||||
aria-label={social.name}
|
||||
>
|
||||
<Icon className="w-4 h-4" />
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Navigation Sections */}
|
||||
<FooterSection
|
||||
title="Explore"
|
||||
links={footerNavigation.Explore}
|
||||
delay={0.1}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Services"
|
||||
links={footerNavigation.Services}
|
||||
delay={0.2}
|
||||
/>
|
||||
<FooterSection
|
||||
title="AI & ML"
|
||||
links={footerNavigation["AI & ML"]}
|
||||
delay={0.3}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Solutions"
|
||||
links={footerNavigation.Solutions}
|
||||
delay={0.4}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Resources"
|
||||
links={footerNavigation.Resources}
|
||||
delay={0.5}
|
||||
/>
|
||||
{/* Navigation Sections */}
|
||||
<FooterSection
|
||||
title="Explore"
|
||||
links={footerNavigation.Explore}
|
||||
delay={0.1}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Services"
|
||||
links={footerNavigation.Services}
|
||||
delay={0.2}
|
||||
/>
|
||||
<FooterSection
|
||||
title="AI & ML"
|
||||
links={footerNavigation["AI & ML"]}
|
||||
delay={0.3}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Solutions"
|
||||
links={footerNavigation.Solutions}
|
||||
delay={0.4}
|
||||
/>
|
||||
<FooterSection
|
||||
title="Resources"
|
||||
links={footerNavigation.Resources}
|
||||
delay={0.5}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Newsletter Subscription Section */}
|
||||
<NewsletterSection />
|
||||
{/* Newsletter Subscription Section */}
|
||||
<NewsletterSection />
|
||||
|
||||
{/* Bottom Bar */}
|
||||
{/* <motion.div
|
||||
{/* Bottom Bar */}
|
||||
{/* <motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6, delay: 0.6 }}
|
||||
@@ -420,7 +420,8 @@ export const Footer = () => {
|
||||
</div>
|
||||
</div>
|
||||
</motion.div> */}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
212
components/HireTalentHeroBanner.tsx
Normal file
212
components/HireTalentHeroBanner.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
import { Button } from "./ui/button";
|
||||
import { ShimmerButton } from "./ui/shimmer-button";
|
||||
import { navigateTo } from "../App";
|
||||
import { DashboardVector } from "./vectors/DashboardVector";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface HireTalentHeroBannerProps {
|
||||
category?: string;
|
||||
title: string;
|
||||
description: string;
|
||||
primaryCTA: {
|
||||
text: string;
|
||||
href: string;
|
||||
icon?: React.ComponentType<{ className?: string }>;
|
||||
};
|
||||
secondaryCTA?: {
|
||||
text: string;
|
||||
href: string;
|
||||
icon?: React.ComponentType<{ className?: string }>;
|
||||
};
|
||||
useVectors?: boolean; // Keep for backward compatibility
|
||||
vectorComponent?: React.ComponentType; // New prop for custom vectors
|
||||
}
|
||||
|
||||
export function HireTalentHeroBanner({
|
||||
category,
|
||||
title,
|
||||
description,
|
||||
primaryCTA,
|
||||
secondaryCTA,
|
||||
useVectors = false,
|
||||
vectorComponent: VectorComponent
|
||||
}: HireTalentHeroBannerProps) {
|
||||
return (
|
||||
<section className="relative py-20 overflow-hidden bg-black">
|
||||
<div className="container mx-auto px-6 lg:px-8">
|
||||
<div className="grid lg:grid-cols-2 gap-16 items-center min-h-[90vh]">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="space-y-8"
|
||||
>
|
||||
{/* Category Label */}
|
||||
{category && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<span className="text-white/70 text-sm font-medium font-manrope">
|
||||
{category}
|
||||
</span>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* Main Heading */}
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-semibold text-white leading-tight font-manrope">
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
<p className="text-lg text-gray-300 leading-relaxed max-w-lg font-manrope">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* CTAs */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
className="flex flex-col sm:flex-row gap-4"
|
||||
>
|
||||
<ShimmerButton
|
||||
className="text-lg px-8 py-4 font-manrope"
|
||||
onClick={() => navigateTo(primaryCTA.href)}
|
||||
>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
{primaryCTA.icon && <primaryCTA.icon className="w-5 h-5 flex-shrink-0" />}
|
||||
<span>{primaryCTA.text}</span>
|
||||
</div>
|
||||
</ShimmerButton>
|
||||
|
||||
{secondaryCTA && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="text-lg px-8 py-4 h-auto border-gray-600 text-gray-300 hover:bg-gray-800 hover:text-white font-manrope"
|
||||
onClick={() => navigateTo(secondaryCTA.href)}
|
||||
>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
{secondaryCTA.icon && <secondaryCTA.icon className="w-5 h-5 flex-shrink-0" />}
|
||||
<span>{secondaryCTA.text}</span>
|
||||
</div>
|
||||
</Button>
|
||||
)}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right side with Custom Vector, Dashboard Vector, or Legacy Vector Graphics */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="relative flex flex-col items-center"
|
||||
>
|
||||
<div className="relative w-full max-w-2xl mx-auto">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="relative"
|
||||
>
|
||||
{VectorComponent ? (
|
||||
/* Custom Vector Component */
|
||||
<VectorComponent />
|
||||
) : useVectors ? (
|
||||
/* Legacy Vector Graphics Version */
|
||||
<DevelopmentTeamVectors />
|
||||
) : (
|
||||
/* Default Dashboard Vector */
|
||||
<DashboardVector />
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
// Legacy Vector Graphics Component for Development Team Visualization (kept for backward compatibility)
|
||||
const DevelopmentTeamVectors = () => {
|
||||
return (
|
||||
<div className="relative w-full h-[500px] flex items-center justify-center">
|
||||
{/* Main Development Hub */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="relative"
|
||||
>
|
||||
{/* Central Hub Circle */}
|
||||
<div className="w-48 h-48 bg-gradient-to-br from-accent to-purple-600 rounded-full flex items-center justify-center relative">
|
||||
<div className="w-32 h-32 bg-white/20 rounded-full flex items-center justify-center backdrop-blur-sm">
|
||||
<svg className="w-16 h-16 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Pulse Animation Ring */}
|
||||
<div className="absolute inset-0 rounded-full bg-accent/30 animate-ping"></div>
|
||||
</div>
|
||||
|
||||
{/* Orbiting Developer Icons */}
|
||||
<motion.div
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||||
className="absolute inset-0 w-48 h-48"
|
||||
>
|
||||
{/* Frontend Developer */}
|
||||
<div className="absolute -top-6 left-1/2 transform -translate-x-1/2 w-12 h-12 bg-gradient-to-br from-blue-500 to-blue-600 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="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Backend Developer */}
|
||||
<div className="absolute top-1/2 -right-6 transform -translate-y-1/2 w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 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="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Mobile Developer */}
|
||||
<div className="absolute -bottom-6 left-1/2 transform -translate-x-1/2 w-12 h-12 bg-gradient-to-br from-purple-500 to-purple-600 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="M12 18h.01M8 21h8a1 1 0 001-1V4a1 1 0 00-1-1H8a1 1 0 00-1 1v16a1 1 0 001 1z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* UI/UX Designer */}
|
||||
<div className="absolute top-1/2 -left-6 transform -translate-y-1/2 w-12 h-12 bg-gradient-to-br from-orange-500 to-orange-600 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="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.536L16.732 3.732z" />
|
||||
</svg>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Skill Badges */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8 }}
|
||||
className="absolute -bottom-16 left-1/2 transform -translate-x-1/2 flex gap-2"
|
||||
>
|
||||
<div className="px-3 py-1 bg-blue-500/20 text-blue-300 border border-blue-500/30 rounded-full text-sm font-manrope">
|
||||
React
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-green-500/20 text-green-300 border border-green-500/30 rounded-full text-sm font-manrope">
|
||||
Node.js
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-purple-500/20 text-purple-300 border border-purple-500/30 rounded-full text-sm font-manrope">
|
||||
Mobile
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
285
components/vectors/BackendVector.tsx
Normal file
285
components/vectors/BackendVector.tsx
Normal file
@@ -0,0 +1,285 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const BackendVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center overflow-hidden font-manrope">
|
||||
{/* Subtle Background Grid */}
|
||||
<div className="absolute inset-0 opacity-5">
|
||||
<svg className="w-full h-full" viewBox="0 0 400 400" fill="none">
|
||||
<defs>
|
||||
<pattern id="gridPattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
|
||||
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#E5195E" strokeWidth="0.5"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#gridPattern)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 flex items-center justify-center">
|
||||
{/* API Gateway - Central Component */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="relative flex flex-col items-center"
|
||||
>
|
||||
{/* Main API Gateway */}
|
||||
<motion.div
|
||||
animate={{ y: [0, -6, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
|
||||
className="w-20 h-16 bg-gradient-to-br from-blue-600 to-blue-800 rounded-xl flex items-center justify-center shadow-lg border border-blue-500/20 relative"
|
||||
>
|
||||
{/* API Icon */}
|
||||
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
|
||||
{/* Pulsing Status Light */}
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.3, 1], opacity: [0.8, 1, 0.8] }}
|
||||
transition={{ duration: 2, repeat: Infinity }}
|
||||
className="absolute -top-1 -right-1 w-3 h-3 bg-green-400 rounded-full"
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* API Gateway Label */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1 }}
|
||||
className="mt-3 text-xs text-white font-manrope whitespace-nowrap"
|
||||
>
|
||||
API Gateway
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Database Cluster - Left Side */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -60 }}
|
||||
animate={{ opacity: 1, x: -80 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="absolute flex flex-col items-center space-y-2"
|
||||
>
|
||||
{Array.from({ length: 3 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={`db-${i}`}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.6 + i * 0.1 }}
|
||||
className="relative"
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
rotateY: [0, 360],
|
||||
scale: [1, 1.05, 1]
|
||||
}}
|
||||
transition={{
|
||||
duration: 8 + i * 2,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
delay: i * 1
|
||||
}}
|
||||
className="w-12 h-8 bg-gradient-to-r from-green-600 to-green-700 rounded-lg flex items-center justify-center border border-green-500/20"
|
||||
>
|
||||
{/* Database Icon */}
|
||||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M3 12v3c0 1.657 3.134 3 7 3s7-1.343 7-3v-3c0 1.657-3.134 3-7 3s-7-1.343-7-3z"/>
|
||||
<path d="M3 7v3c0 1.657 3.134 3 7 3s7-1.343 7-3V7c0 1.657-3.134 3-7 3S3 8.657 3 7z"/>
|
||||
<path d="M17 5c0 1.657-3.134 3-7 3S3 6.657 3 5s3.134-3 7-3 7 1.343 7 3z"/>
|
||||
</svg>
|
||||
</motion.div>
|
||||
|
||||
{/* Activity Indicator */}
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.5, 1] }}
|
||||
transition={{ duration: 1.5, repeat: Infinity, delay: i * 0.5 }}
|
||||
className="absolute -top-1 -right-1 w-2 h-2 bg-blue-400 rounded-full"
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Database Label */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.2 }}
|
||||
className="text-xs text-white font-manrope whitespace-nowrap"
|
||||
>
|
||||
Database
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Microservices - Right Side */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 60 }}
|
||||
animate={{ opacity: 1, x: 80 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
className="absolute flex flex-col items-center space-y-2"
|
||||
>
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={`service-${i}`}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.4, delay: 0.8 + i * 0.1 }}
|
||||
className="relative"
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
x: [0, 3, 0],
|
||||
scale: [1, 1.1, 1]
|
||||
}}
|
||||
transition={{
|
||||
duration: 3 + i * 0.5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: i * 0.3
|
||||
}}
|
||||
className="w-10 h-6 bg-gradient-to-r from-purple-600 to-purple-700 rounded flex items-center justify-center border border-purple-500/20"
|
||||
>
|
||||
<span className="text-xs text-white font-manrope">#{i + 1}</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Service Status */}
|
||||
<motion.div
|
||||
animate={{ opacity: [0.5, 1, 0.5] }}
|
||||
transition={{ duration: 2, repeat: Infinity, delay: i * 0.4 }}
|
||||
className="absolute -top-1 -left-1 w-2 h-2 bg-green-400 rounded-full"
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Microservices Label */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.4 }}
|
||||
className="text-xs text-white font-manrope whitespace-nowrap"
|
||||
>
|
||||
Services
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Data Flow Lines */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-30 z-15">
|
||||
<defs>
|
||||
<linearGradient id="flowGradient1" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#22c55e" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#3b82f6" stopOpacity="0.8" />
|
||||
<stop offset="100%" stopColor="#8b5cf6" stopOpacity="0.6" />
|
||||
</linearGradient>
|
||||
<linearGradient id="flowGradient2" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#8b5cf6" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#3b82f6" stopOpacity="0.8" />
|
||||
<stop offset="100%" stopColor="#22c55e" stopOpacity="0.6" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{/* Database to API Flow */}
|
||||
<motion.path
|
||||
d="M 30% 50% Q 40% 45% 50% 50%"
|
||||
fill="none"
|
||||
stroke="url(#flowGradient1)"
|
||||
strokeWidth="2"
|
||||
strokeDasharray="4,4"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2, repeat: Infinity, repeatType: "loop" }}
|
||||
/>
|
||||
|
||||
{/* API to Services Flow */}
|
||||
<motion.path
|
||||
d="M 50% 50% Q 60% 45% 70% 50%"
|
||||
fill="none"
|
||||
stroke="url(#flowGradient2)"
|
||||
strokeWidth="2"
|
||||
strokeDasharray="4,4"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2, repeat: Infinity, repeatType: "loop", delay: 0.5 }}
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Performance Metrics - Top Right */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 1.6 }}
|
||||
className="absolute top-6 right-6 z-25"
|
||||
>
|
||||
<div className="bg-black/40 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">2ms Latency</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">1M+ Requests/hr</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.2, 1] }}
|
||||
transition={{ duration: 2, repeat: Infinity, delay: 1 }}
|
||||
className="w-2 h-2 bg-purple-400 rounded-full"
|
||||
></motion.div>
|
||||
<span className="text-purple-400 text-xs font-manrope">Auto-Scaling</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Tech Stack - Bottom Left */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 1.8 }}
|
||||
className="absolute bottom-6 left-6 z-25"
|
||||
>
|
||||
<div className="bg-black/40 backdrop-blur-sm rounded-lg p-3 border border-white/10">
|
||||
<div className="flex space-x-2">
|
||||
{[
|
||||
{ name: "Node.js", color: "bg-green-600/20 text-green-400" },
|
||||
{ name: "SQL", color: "bg-blue-600/20 text-blue-400" },
|
||||
{ name: "Redis", color: "bg-red-600/20 text-red-400" },
|
||||
{ name: "Docker", color: "bg-cyan-600/20 text-cyan-400" }
|
||||
].map((tech, index) => (
|
||||
<motion.div
|
||||
key={tech.name}
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.3, delay: 2 + index * 0.1 }}
|
||||
className={`px-2 py-1 ${tech.color} border border-current/20 rounded text-xs font-manrope`}
|
||||
>
|
||||
{tech.name}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Load Balancer Indicator */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 2.2 }}
|
||||
className="absolute bottom-6 right-6 z-25"
|
||||
>
|
||||
<motion.div
|
||||
animate={{ rotate: [0, 360] }}
|
||||
transition={{ duration: 12, repeat: Infinity, ease: "linear" }}
|
||||
className="w-8 h-8 border-2 border-gray-600 border-t-accent rounded-full"
|
||||
></motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
232
components/vectors/DashboardVector.tsx
Normal file
232
components/vectors/DashboardVector.tsx
Normal file
@@ -0,0 +1,232 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const DashboardVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Main Mobile Device */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
{/* Phone Frame */}
|
||||
<div className="w-40 h-80 bg-gradient-to-br from-gray-800 to-gray-900 rounded-3xl p-2 shadow-2xl">
|
||||
{/* Screen */}
|
||||
<div className="w-full h-full bg-gradient-to-br from-gray-100 to-gray-200 rounded-2xl relative overflow-hidden">
|
||||
{/* Top Status Bar */}
|
||||
<div className="absolute top-0 left-0 right-0 h-8 bg-gradient-to-r from-gray-800 to-gray-700 flex items-center justify-between px-4">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-1 h-1 bg-green-400 rounded-full"></div>
|
||||
<div className="w-1 h-1 bg-yellow-400 rounded-full"></div>
|
||||
<div className="w-1 h-1 bg-red-400 rounded-full"></div>
|
||||
</div>
|
||||
<div className="text-white text-xs font-manrope">9:41</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-3 h-2 bg-white/60 rounded-sm"></div>
|
||||
<div className="w-4 h-2 bg-white/80 rounded-sm"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Dashboard Content */}
|
||||
<div className="absolute inset-4 top-12 space-y-3">
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<div className="text-gray-800 text-sm font-bold font-manrope">Hey Balazs!</div>
|
||||
<div className="text-gray-600 text-xs font-manrope">Good morning</div>
|
||||
</div>
|
||||
<motion.div
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 8, repeat: Infinity, ease: "linear" }}
|
||||
className="w-6 h-6 bg-gradient-to-br from-[#E5195E] to-[#FF6B9D] rounded-full flex items-center justify-center"
|
||||
>
|
||||
<div className="w-3 h-3 bg-white rounded-full"></div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Weather Card */}
|
||||
<div className="bg-gradient-to-r from-blue-400 to-blue-500 rounded-2xl p-3 text-white">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<div className="text-lg font-bold font-manrope">17°</div>
|
||||
<div className="text-xs opacity-80 font-manrope">New York</div>
|
||||
</div>
|
||||
<div className="text-2xl">☀️</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Row */}
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="bg-white rounded-xl p-2 shadow-sm">
|
||||
<div className="text-gray-500 text-xs font-manrope">Revenue</div>
|
||||
<div className="text-gray-800 text-sm font-bold font-manrope">$67k</div>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "70%" }}
|
||||
transition={{ duration: 2, delay: 1 }}
|
||||
className="h-1 bg-gradient-to-r from-[#E5195E] to-[#FF6B9D] rounded-full mt-1"
|
||||
></motion.div>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl p-2 shadow-sm">
|
||||
<div className="text-gray-500 text-xs font-manrope">Orders</div>
|
||||
<div className="text-gray-800 text-sm font-bold font-manrope">1,284</div>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "85%" }}
|
||||
transition={{ duration: 2, delay: 1.2 }}
|
||||
className="h-1 bg-gradient-to-r from-green-400 to-green-500 rounded-full mt-1"
|
||||
></motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Chart Area */}
|
||||
<div className="bg-white rounded-xl p-3 shadow-sm">
|
||||
<div className="text-gray-500 text-xs mb-2 font-manrope">Analytics</div>
|
||||
<div className="flex items-end justify-between h-16">
|
||||
{[40, 65, 45, 80, 55, 90, 70].map((height, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ height: 0 }}
|
||||
animate={{ height: `${height}%` }}
|
||||
transition={{ duration: 1, delay: 1.5 + index * 0.1 }}
|
||||
className="w-2 bg-gradient-to-t from-[#E5195E] to-[#FF6B9D] rounded-full"
|
||||
></motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Activity Indicator */}
|
||||
<div className="bg-white rounded-xl p-3 shadow-sm">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-gray-500 text-xs font-manrope">Activity</div>
|
||||
<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>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<svg className="w-full h-6" viewBox="0 0 100 20">
|
||||
<motion.path
|
||||
d="M0,15 Q25,5 50,10 T100,8"
|
||||
stroke="url(#activityGradient)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2, delay: 2 }}
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient id="activityGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#E5195E" />
|
||||
<stop offset="100%" stopColor="#FF6B9D" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Navigation */}
|
||||
<div className="absolute bottom-0 left-0 right-0 h-12 bg-white border-t border-gray-200 flex items-center justify-around">
|
||||
{['🏠', '📊', '💬', '⚙️'].map((icon, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
whileHover={{ scale: 1.2 }}
|
||||
className={`text-lg ${index === 1 ? 'text-[#E5195E]' : 'text-gray-400'}`}
|
||||
>
|
||||
{icon}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Floating Data Points */}
|
||||
<motion.div
|
||||
animate={{ y: [0, -10, 0] }}
|
||||
transition={{ duration: 3, repeat: Infinity }}
|
||||
className="absolute top-20 left-16 w-12 h-12 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-sm font-bold font-manrope">98%</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -15, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, delay: 0.5 }}
|
||||
className="absolute top-24 right-20 w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-xs font-bold font-manrope">+24</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -12, 0] }}
|
||||
transition={{ duration: 3.5, repeat: Infinity, delay: 1 }}
|
||||
className="absolute bottom-24 left-20 w-11 h-11 bg-gradient-to-br from-purple-500 to-purple-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-xs font-bold font-manrope">📈</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -8, 0] }}
|
||||
transition={{ duration: 2.5, repeat: Infinity, delay: 1.5 }}
|
||||
className="absolute bottom-20 right-16 w-9 h-9 bg-gradient-to-br from-orange-500 to-orange-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-xs font-bold font-manrope">⚡</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Connection Lines */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-30">
|
||||
<defs>
|
||||
<linearGradient id="dashboardGradient" 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>
|
||||
|
||||
<motion.path
|
||||
d="M 25% 35% Q 50% 15% 75% 40%"
|
||||
stroke="url(#dashboardGradient)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="4,4"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse" }}
|
||||
/>
|
||||
|
||||
<motion.path
|
||||
d="M 20% 65% Q 50% 85% 80% 60%"
|
||||
stroke="url(#dashboardGradient)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="4,4"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2.5, repeat: Infinity, repeatType: "reverse", delay: 0.5 }}
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Technology Labels */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 2.5 }}
|
||||
className="absolute bottom-8 left-1/2 transform -translate-x-1/2 flex space-x-4"
|
||||
>
|
||||
<div className="px-3 py-1 bg-blue-500/20 text-blue-300 border border-blue-500/30 rounded-full text-sm font-manrope">
|
||||
React Native
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-green-500/20 text-green-300 border border-green-500/30 rounded-full text-sm font-manrope">
|
||||
Dashboard
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-purple-500/20 text-purple-300 border border-purple-500/30 rounded-full text-sm font-manrope">
|
||||
Analytics
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
160
components/vectors/DeveloperSkillsVector.tsx
Normal file
160
components/vectors/DeveloperSkillsVector.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const DeveloperSkillsVector = () => {
|
||||
const skills = [
|
||||
{ name: "Frontend", color: "from-blue-500 to-blue-600", icon: "🎨", position: { x: -60, y: -30 } },
|
||||
{ name: "Backend", color: "from-green-500 to-green-600", icon: "⚙️", position: { x: 60, y: -30 } },
|
||||
{ name: "Database", color: "from-purple-500 to-purple-600", icon: "🗄️", position: { x: 0, y: 50 } }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-80 flex items-center justify-center font-manrope">
|
||||
{/* Subtle Background Glow */}
|
||||
<div className="absolute inset-0 opacity-10">
|
||||
<svg className="w-full h-full" viewBox="0 0 400 400" fill="none">
|
||||
<defs>
|
||||
<radialGradient id="bgGlow" cx="50%" cy="50%" r="40%">
|
||||
<stop offset="0%" stopColor="#E5195E" stopOpacity="0.08" />
|
||||
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.02" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="200" cy="200" r="120" fill="url(#bgGlow)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Central Developer Icon */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-20"
|
||||
>
|
||||
<motion.div
|
||||
animate={{ y: [0, -8, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
|
||||
className="w-20 h-20 bg-gradient-to-br from-accent to-purple-600 rounded-2xl flex items-center justify-center shadow-xl border border-white/10"
|
||||
>
|
||||
<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="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>
|
||||
</motion.div>
|
||||
|
||||
{/* Skill Badges */}
|
||||
{skills.map((skill, index) => (
|
||||
<motion.div
|
||||
key={skill.name}
|
||||
initial={{ opacity: 0, scale: 0, x: 0, y: 0 }}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
x: skill.position.x,
|
||||
y: skill.position.y
|
||||
}}
|
||||
transition={{
|
||||
duration: 0.6,
|
||||
delay: 0.4 + index * 0.2,
|
||||
type: "spring",
|
||||
stiffness: 100
|
||||
}}
|
||||
className="absolute z-10"
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
y: [0, -6, 0],
|
||||
scale: [1, 1.05, 1]
|
||||
}}
|
||||
transition={{
|
||||
duration: 3 + index * 0.5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: index * 0.8
|
||||
}}
|
||||
className={`w-16 h-16 bg-gradient-to-br ${skill.color} rounded-xl flex items-center justify-center shadow-lg border border-white/20`}
|
||||
>
|
||||
<span className="text-2xl">{skill.icon}</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Skill Label */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.4, delay: 0.8 + index * 0.2 }}
|
||||
className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-white text-xs font-manrope whitespace-nowrap"
|
||||
>
|
||||
{skill.name}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Subtle Connecting Elements */}
|
||||
<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="#E5195E" stopOpacity="0.3" />
|
||||
<stop offset="50%" stopColor="#3B82F6" stopOpacity="0.2" />
|
||||
<stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.3" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{skills.map((skill, index) => (
|
||||
<motion.line
|
||||
key={`connection-${index}`}
|
||||
x1="50%"
|
||||
y1="50%"
|
||||
x2={`${50 + (skill.position.x / 4)}%`}
|
||||
y2={`${50 + (skill.position.y / 4)}%`}
|
||||
stroke="url(#connectionGradient)"
|
||||
strokeWidth="1"
|
||||
strokeDasharray="2,4"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 1 }}
|
||||
transition={{ duration: 1.5, delay: 1 + index * 0.3 }}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
|
||||
{/* Status Indicator */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.8 }}
|
||||
className="absolute top-8 right-8 z-25"
|
||||
>
|
||||
<div className="bg-black/30 backdrop-blur-sm rounded-lg px-3 py-2 border border-white/10">
|
||||
<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">Available</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Experience Level */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 2 }}
|
||||
className="absolute bottom-8 left-1/2 transform -translate-x-1/2 z-25"
|
||||
>
|
||||
<div className="bg-black/30 backdrop-blur-sm rounded-lg px-4 py-2 border border-white/10">
|
||||
<div className="flex items-center space-x-3">
|
||||
{[1, 2, 3, 4, 5].map((star, index) => (
|
||||
<motion.div
|
||||
key={star}
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.3, delay: 2.2 + index * 0.1 }}
|
||||
className="w-3 h-3 bg-yellow-400 rounded-full"
|
||||
></motion.div>
|
||||
))}
|
||||
<span className="text-white text-xs font-manrope ml-2">Expert Level</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
200
components/vectors/EngagementModelsVector.tsx
Normal file
200
components/vectors/EngagementModelsVector.tsx
Normal file
@@ -0,0 +1,200 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const EngagementModelsVector = () => {
|
||||
const models = [
|
||||
{ name: "Fixed Price", icon: "💰", color: "from-blue-500 to-blue-600", position: { x: 20, y: 30 } },
|
||||
{ name: "Time & Material", icon: "⏱️", color: "from-green-500 to-green-600", position: { x: 80, y: 30 } },
|
||||
{ name: "Dedicated Team", icon: "👥", color: "from-accent to-pink-600", position: { x: 50, y: 70 } }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Central Business Hub */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
<div className="w-32 h-32 bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl flex items-center justify-center shadow-2xl">
|
||||
<div className="w-20 h-20 bg-gradient-to-br from-accent to-purple-600 rounded-xl flex items-center justify-center">
|
||||
<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="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2-2v2m8 0V6a2 2 0 012 2v6a2 2 0 01-2 2H6a2 2 0 01-2-2V8a2 2 0 012-2V6" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Engagement Model Options */}
|
||||
{models.map((model, index) => (
|
||||
<motion.div
|
||||
key={model.name}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.6, delay: index * 0.2 + 0.4 }}
|
||||
className="absolute"
|
||||
style={{
|
||||
left: `${model.position.x}%`,
|
||||
top: `${model.position.y}%`,
|
||||
transform: 'translate(-50%, -50%)'
|
||||
}}
|
||||
>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1, y: -5 }}
|
||||
className={`w-20 h-20 bg-gradient-to-br ${model.color} rounded-xl flex flex-col items-center justify-center shadow-lg cursor-pointer`}
|
||||
>
|
||||
<span className="text-2xl mb-1">{model.icon}</span>
|
||||
<span className="text-white text-xs font-manrope text-center leading-tight">
|
||||
{model.name.split(' ').map((word, i) => (
|
||||
<div key={i}>{word}</div>
|
||||
))}
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Model Benefits */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: index * 0.2 + 1 }}
|
||||
className="absolute -bottom-12 left-1/2 transform -translate-x-1/2 text-center"
|
||||
>
|
||||
<div className="text-gray-400 text-xs font-manrope">
|
||||
{model.name === "Fixed Price" && "Predictable Cost"}
|
||||
{model.name === "Time & Material" && "High Flexibility"}
|
||||
{model.name === "Dedicated Team" && "Full Control"}
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Connection Lines */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none">
|
||||
<defs>
|
||||
<linearGradient id="engagementGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#3B82F6" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#E5195E" stopOpacity="0.8" />
|
||||
<stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.6" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{models.map((model, index) => (
|
||||
<motion.line
|
||||
key={index}
|
||||
x1="50%"
|
||||
y1="50%"
|
||||
x2={`${model.position.x}%`}
|
||||
y2={`${model.position.y}%`}
|
||||
stroke="url(#engagementGradient)"
|
||||
strokeWidth="2"
|
||||
strokeDasharray="4,4"
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{ pathLength: 1, opacity: 0.7 }}
|
||||
transition={{ duration: 1, delay: index * 0.3 + 1.5 }}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
|
||||
{/* Business Metrics */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 2 }}
|
||||
className="absolute top-8 left-1/2 transform -translate-x-1/2 flex space-x-6"
|
||||
>
|
||||
<div className="text-center">
|
||||
<div className="text-green-400 text-lg font-manrope">95%</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Success Rate</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-blue-400 text-lg font-manrope">500+</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Projects</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-purple-400 text-lg font-manrope">98%</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Satisfaction</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Project Types */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 2.5 }}
|
||||
className="absolute bottom-8 left-1/2 transform -translate-x-1/2"
|
||||
>
|
||||
<div className="flex space-x-3">
|
||||
<div className="px-3 py-1 bg-blue-500/20 text-blue-300 border border-blue-500/30 rounded-full text-sm font-manrope">
|
||||
MVP
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-green-500/20 text-green-300 border border-green-500/30 rounded-full text-sm font-manrope">
|
||||
Enterprise
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-purple-500/20 text-purple-300 border border-purple-500/30 rounded-full text-sm font-manrope">
|
||||
Scale-up
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Floating Decision Factors */}
|
||||
<motion.div
|
||||
animate={{ y: [0, -8, 0] }}
|
||||
transition={{ duration: 3, repeat: Infinity }}
|
||||
className="absolute top-24 left-8 w-16 h-12 bg-gradient-to-br from-yellow-500 to-yellow-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<div className="text-center">
|
||||
<div className="text-white text-xs font-manrope">Budget</div>
|
||||
<div className="text-white text-xs font-manrope">🎯</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -12, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, delay: 0.5 }}
|
||||
className="absolute top-32 right-8 w-16 h-12 bg-gradient-to-br from-indigo-500 to-indigo-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<div className="text-center">
|
||||
<div className="text-white text-xs font-manrope">Timeline</div>
|
||||
<div className="text-white text-xs font-manrope">⏰</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -10, 0] }}
|
||||
transition={{ duration: 3.5, repeat: Infinity, delay: 1 }}
|
||||
className="absolute bottom-20 left-8 w-16 h-12 bg-gradient-to-br from-teal-500 to-teal-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<div className="text-center">
|
||||
<div className="text-white text-xs font-manrope">Scope</div>
|
||||
<div className="text-white text-xs font-manrope">📋</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* ROI Indicator */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, rotate: -45 }}
|
||||
animate={{ opacity: 1, rotate: 0 }}
|
||||
transition={{ duration: 0.8, delay: 3 }}
|
||||
className="absolute bottom-16 right-8"
|
||||
>
|
||||
<div className="w-20 h-8 bg-gradient-to-br from-green-500 to-green-600 rounded-full flex items-center justify-center shadow-lg">
|
||||
<span className="text-white text-sm font-manrope">ROI ↗</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Selection Process Flow */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 3.5 }}
|
||||
className="absolute bottom-24 right-16"
|
||||
>
|
||||
<div className="text-right space-y-1">
|
||||
<div className="text-gray-400 text-xs font-manrope">1. Analyze Requirements</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">2. Compare Models</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">3. Select Best Fit</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">4. Start Project</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
195
components/vectors/FrontendVector.tsx
Normal file
195
components/vectors/FrontendVector.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const FrontendVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Browser Window */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
<div className="w-80 h-56 bg-gradient-to-br from-gray-800 to-gray-900 rounded-lg shadow-2xl">
|
||||
{/* Browser Header */}
|
||||
<div className="h-8 bg-gray-700 rounded-t-lg flex items-center px-4 space-x-2">
|
||||
<div className="w-3 h-3 bg-red-500 rounded-full"></div>
|
||||
<div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
|
||||
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
|
||||
<div className="flex-1 bg-gray-600 rounded ml-4 h-4 flex items-center px-2">
|
||||
<span className="text-gray-300 text-xs font-manrope">localhost:3000</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Browser Content */}
|
||||
<div className="p-4 space-y-3">
|
||||
{/* Navigation */}
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="h-3 bg-gradient-to-r from-blue-500 to-purple-500 rounded w-20"></div>
|
||||
<div className="flex space-x-2">
|
||||
<div className="w-12 h-3 bg-gray-600 rounded"></div>
|
||||
<div className="w-12 h-3 bg-gray-600 rounded"></div>
|
||||
<div className="w-12 h-3 bg-accent rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="space-y-2">
|
||||
<div className="h-4 bg-white/80 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-white/60 rounded w-1/2"></div>
|
||||
<div className="h-6 bg-gradient-to-r from-accent to-purple-500 rounded w-24 mt-2"></div>
|
||||
</div>
|
||||
|
||||
{/* Cards Grid */}
|
||||
<div className="grid grid-cols-3 gap-2 mt-4">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.3, delay: i * 0.1 + 1 }}
|
||||
className="h-8 bg-gradient-to-br from-gray-600 to-gray-700 rounded"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Floating UI Components */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.5 }}
|
||||
className="absolute left-8 top-16"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{/* Button Component */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="w-20 h-8 bg-gradient-to-r from-blue-500 to-blue-600 rounded flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">Button</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Input Component */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="w-24 h-6 bg-gray-700 border border-gray-500 rounded flex items-center px-2"
|
||||
>
|
||||
<div className="w-2 h-2 bg-blue-400 animate-pulse"></div>
|
||||
</motion.div>
|
||||
|
||||
{/* Card Component */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="w-20 h-12 bg-gradient-to-br from-gray-700 to-gray-800 rounded shadow-lg border border-gray-600"
|
||||
>
|
||||
<div className="p-2 space-y-1">
|
||||
<div className="h-1 bg-gray-400 rounded w-3/4"></div>
|
||||
<div className="h-1 bg-gray-500 rounded w-1/2"></div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Floating Code Snippets */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.7 }}
|
||||
className="absolute right-8 top-20"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{/* JSX Code */}
|
||||
<div className="w-28 h-10 bg-gray-800 rounded border border-gray-600 p-2">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="text-purple-400 text-xs font-manrope"><</div>
|
||||
<div className="text-blue-400 text-xs font-manrope">div</div>
|
||||
<div className="text-purple-400 text-xs font-manrope">></div>
|
||||
</div>
|
||||
<div className="h-1 bg-green-400 rounded w-2/3 ml-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CSS Code */}
|
||||
<div className="w-24 h-8 bg-gray-800 rounded border border-gray-600 p-1.5">
|
||||
<div className="space-y-0.5">
|
||||
<div className="text-orange-400 text-xs font-manrope">.btn</div>
|
||||
<div className="h-0.5 bg-blue-400 rounded w-1/2 ml-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Technology Icons */}
|
||||
<motion.div
|
||||
animate={{ y: [0, -10, 0] }}
|
||||
transition={{ duration: 3, repeat: Infinity }}
|
||||
className="absolute bottom-16 left-16 w-12 h-12 bg-gradient-to-br from-cyan-500 to-cyan-600 rounded-xl flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-lg font-manrope">⚛️</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -15, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, delay: 0.5 }}
|
||||
className="absolute bottom-20 right-20 w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-sm font-manrope">V</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
animate={{ y: [0, -12, 0] }}
|
||||
transition={{ duration: 3.5, repeat: Infinity, delay: 1 }}
|
||||
className="absolute top-12 right-32 w-11 h-11 bg-gradient-to-br from-red-500 to-red-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-sm font-manrope">A</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Responsive Design Indicators */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 1.5 }}
|
||||
className="absolute bottom-8 left-1/2 transform -translate-x-1/2 flex space-x-3"
|
||||
>
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-4 h-3 bg-blue-500 rounded-sm"></div>
|
||||
<span className="text-gray-400 text-xs font-manrope">Desktop</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-3 h-4 bg-green-500 rounded-sm"></div>
|
||||
<span className="text-gray-400 text-xs font-manrope">Tablet</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-2 h-4 bg-purple-500 rounded-sm"></div>
|
||||
<span className="text-gray-400 text-xs font-manrope">Mobile</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Interactive Elements */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-30">
|
||||
<defs>
|
||||
<radialGradient id="frontendGradient" cx="50%" cy="50%" r="50%">
|
||||
<stop offset="0%" stopColor="#3B82F6" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#E5195E" stopOpacity="0.4" />
|
||||
<stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.6" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
<motion.circle
|
||||
cx="50%" cy="50%" r="100"
|
||||
stroke="url(#frontendGradient)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="8,8"
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
237
components/vectors/FullStackVector.tsx
Normal file
237
components/vectors/FullStackVector.tsx
Normal file
@@ -0,0 +1,237 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
232
components/vectors/MobileAppVector.tsx
Normal file
232
components/vectors/MobileAppVector.tsx
Normal file
@@ -0,0 +1,232 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const MobileAppVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center overflow-hidden">
|
||||
{/* Subtle Background */}
|
||||
<div className="absolute inset-0 opacity-10">
|
||||
<svg className="w-full h-full" viewBox="0 0 400 400" fill="none">
|
||||
<defs>
|
||||
<radialGradient id="bgGradient" cx="50%" cy="50%" r="40%">
|
||||
<stop offset="0%" stopColor="#E5195E" stopOpacity="0.08" />
|
||||
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.04" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="200" cy="200" r="120" fill="url(#bgGradient)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Main iPhone Device */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="relative z-20"
|
||||
>
|
||||
<div className="relative">
|
||||
{/* iPhone Frame */}
|
||||
<div className="w-40 h-72 bg-gradient-to-br from-gray-800 to-gray-900 rounded-[2rem] p-1.5 shadow-2xl">
|
||||
{/* Screen */}
|
||||
<div className="w-full h-full bg-black rounded-[1.5rem] relative overflow-hidden">
|
||||
{/* Dynamic Island */}
|
||||
<div className="absolute top-2 left-1/2 transform -translate-x-1/2 w-20 h-5 bg-black rounded-full z-30"></div>
|
||||
|
||||
{/* App Interface */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-blue-600 to-purple-700 rounded-[1.5rem]">
|
||||
{/* Status Bar */}
|
||||
<div className="flex justify-between items-center px-4 pt-8 pb-3">
|
||||
<div className="text-white text-xs font-manrope">9:41</div>
|
||||
<div className="flex space-x-1">
|
||||
<div className="w-3 h-1.5 bg-white/80 rounded-sm"></div>
|
||||
<div className="w-3 h-1.5 bg-white/60 rounded-sm"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* App Content */}
|
||||
<div className="px-4 space-y-3">
|
||||
{/* Header */}
|
||||
<div className="text-center">
|
||||
<div className="h-3 bg-white/90 rounded w-24 mx-auto mb-2"></div>
|
||||
<div className="h-2 bg-white/70 rounded w-32 mx-auto"></div>
|
||||
</div>
|
||||
|
||||
{/* Feature Cards */}
|
||||
<div className="space-y-2.5">
|
||||
{Array.from({ length: 3 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ x: -15, opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
transition={{ duration: 0.4, delay: 0.6 + i * 0.1 }}
|
||||
className="bg-white/15 backdrop-blur-sm rounded-lg p-2.5 border border-white/20"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-6 h-6 bg-white/30 rounded-md"></div>
|
||||
<div className="flex-1">
|
||||
<div className={`h-1.5 bg-white/70 rounded mb-1 ${i === 0 ? 'w-20' : i === 1 ? 'w-16' : 'w-18'}`}></div>
|
||||
<div className={`h-1 bg-white/50 rounded ${i === 0 ? 'w-12' : i === 1 ? 'w-14' : 'w-10'}`}></div>
|
||||
</div>
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.1, 1] }}
|
||||
transition={{ duration: 2, repeat: Infinity, delay: i * 0.7 }}
|
||||
className="w-4 h-4 bg-white/40 rounded-full"
|
||||
></motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Bottom Navigation */}
|
||||
<div className="absolute bottom-6 left-4 right-4">
|
||||
<div className="bg-white/10 backdrop-blur-sm rounded-xl p-2 border border-white/20">
|
||||
<div className="flex justify-around">
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
animate={{
|
||||
backgroundColor: i === 1 ? "rgba(255,255,255,0.6)" : "rgba(255,255,255,0.2)",
|
||||
}}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="w-6 h-6 rounded-lg flex items-center justify-center"
|
||||
>
|
||||
<div className="w-3 h-3 bg-white/70 rounded"></div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* React Native Icon */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1 }}
|
||||
className="absolute top-16 left-24 z-25"
|
||||
>
|
||||
<motion.div
|
||||
animate={{ y: [0, -6, 0] }}
|
||||
transition={{ duration: 2.5, repeat: Infinity }}
|
||||
className="w-12 h-12 bg-gradient-to-br from-blue-500 to-cyan-500 rounded-xl flex items-center justify-center shadow-lg border border-white/20"
|
||||
>
|
||||
<span className="text-white text-sm font-manrope">⚛️</span>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Code Window */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: 1.2 }}
|
||||
className="absolute top-20 right-16 z-25"
|
||||
>
|
||||
<div className="bg-gray-900/80 backdrop-blur-sm rounded-lg p-2 border border-gray-700 shadow-lg w-24">
|
||||
<div className="flex items-center space-x-1 mb-1">
|
||||
<div className="w-1.5 h-1.5 bg-red-500 rounded-full"></div>
|
||||
<div className="w-1.5 h-1.5 bg-yellow-500 rounded-full"></div>
|
||||
<div className="w-1.5 h-1.5 bg-green-500 rounded-full"></div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "70%" }}
|
||||
transition={{ duration: 0.8, delay: 1.5 }}
|
||||
className="h-0.5 bg-blue-400 rounded"
|
||||
></motion.div>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "50%" }}
|
||||
transition={{ duration: 0.8, delay: 1.7 }}
|
||||
className="h-0.5 bg-green-400 rounded"
|
||||
></motion.div>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "80%" }}
|
||||
transition={{ duration: 0.8, delay: 1.9 }}
|
||||
className="h-0.5 bg-purple-400 rounded"
|
||||
></motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* App Store & Google Play */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 1.4 }}
|
||||
className="absolute bottom-12 left-20 z-25"
|
||||
>
|
||||
<div className="flex space-x-2">
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
animate={{ rotate: [0, 2, -2, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity }}
|
||||
className="w-10 h-10 bg-gradient-to-br from-blue-600 to-blue-700 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-sm font-manrope">📱</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
animate={{ rotate: [0, -2, 2, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, delay: 2 }}
|
||||
className="w-10 h-10 bg-gradient-to-br from-green-600 to-green-700 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<span className="text-white text-sm font-manrope">🤖</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Technology Labels */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.8, delay: 2 }}
|
||||
className="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2 z-30"
|
||||
>
|
||||
{[
|
||||
{ name: "iOS", color: "from-blue-500 to-blue-600" },
|
||||
{ name: "Android", color: "from-green-500 to-green-600" },
|
||||
{ name: "React Native", color: "from-cyan-500 to-cyan-600" }
|
||||
].map((tech, index) => (
|
||||
<motion.div
|
||||
key={tech.name}
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.3, delay: 2.2 + index * 0.1 }}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className={`px-2 py-1 bg-gradient-to-r ${tech.color} bg-opacity-20 text-white border border-white/20 rounded-full text-xs font-manrope backdrop-blur-sm`}
|
||||
>
|
||||
{tech.name}
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Subtle Connecting Line */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-20 z-5">
|
||||
<defs>
|
||||
<linearGradient id="connectionGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#E5195E" stopOpacity="0.4" />
|
||||
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.4" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<motion.path
|
||||
d="M 30% 40% Q 50% 30% 70% 50%"
|
||||
stroke="url(#connectionGradient)"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
strokeDasharray="3,3"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse", delay: 2.5 }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
103
components/vectors/ProjectTimelineVector.tsx
Normal file
103
components/vectors/ProjectTimelineVector.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const ProjectTimelineVector = () => {
|
||||
const phases = [
|
||||
{ name: "Planning", icon: "📋", color: "from-blue-500 to-blue-600", duration: "Week 1-2" },
|
||||
{ name: "Design", icon: "🎨", color: "from-purple-500 to-purple-600", duration: "Week 3-4" },
|
||||
{ name: "Development", icon: "⚡", color: "from-green-500 to-green-600", duration: "Week 5-12" },
|
||||
{ name: "Testing", icon: "🔍", color: "from-orange-500 to-orange-600", duration: "Week 13-14" },
|
||||
{ name: "Launch", icon: "🚀", color: "from-red-500 to-red-600", duration: "Week 15-16" }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-80 bg-gradient-to-br from-gray-900/50 to-gray-800/50 rounded-2xl border border-white/10 p-8">
|
||||
{/* Timeline Line */}
|
||||
<div className="absolute left-8 top-16 bottom-16 w-1 bg-gradient-to-b from-accent to-purple-600"></div>
|
||||
|
||||
{/* Project Phases */}
|
||||
<div className="space-y-8 ml-12">
|
||||
{phases.map((phase, index) => (
|
||||
<motion.div
|
||||
key={phase.name}
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: index * 0.2 }}
|
||||
className="relative flex items-center space-x-4"
|
||||
>
|
||||
{/* Timeline Dot */}
|
||||
<motion.div
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.4, delay: index * 0.2 + 0.3 }}
|
||||
className={`absolute -left-16 w-4 h-4 bg-gradient-to-br ${phase.color} rounded-full border-2 border-white shadow-lg`}
|
||||
/>
|
||||
|
||||
{/* Phase Card */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.02, y: -2 }}
|
||||
className="flex-1 bg-white/5 border border-white/10 rounded-lg p-4 backdrop-blur-sm hover:bg-white/10 transition-all duration-300"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-3">
|
||||
<span className="text-2xl">{phase.icon}</span>
|
||||
<div>
|
||||
<h3 className="text-white font-semibold font-manrope">{phase.name}</h3>
|
||||
<p className="text-white/60 text-sm font-manrope">{phase.duration}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Progress Indicator */}
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "100%" }}
|
||||
transition={{ duration: 1, delay: index * 0.3 + 1 }}
|
||||
className="w-16 h-2 bg-gray-700 rounded-full overflow-hidden"
|
||||
>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: `${(index + 1) * 20}%` }}
|
||||
transition={{ duration: 1, delay: index * 0.3 + 1.5 }}
|
||||
className={`h-full bg-gradient-to-r ${phase.color} rounded-full`}
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Connecting Arrow */}
|
||||
{index < phases.length - 1 && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.4, delay: index * 0.2 + 0.8 }}
|
||||
className="absolute -bottom-4 left-8 text-white/40"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
||||
</svg>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Success Metrics */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 2 }}
|
||||
className="absolute bottom-4 right-4 flex space-x-4"
|
||||
>
|
||||
{[
|
||||
{ label: "On Time", value: "95%", color: "text-green-400" },
|
||||
{ label: "Quality", value: "5★", color: "text-yellow-400" },
|
||||
{ label: "Satisfaction", value: "98%", color: "text-blue-400" }
|
||||
].map((metric, index) => (
|
||||
<div key={metric.label} className="text-center">
|
||||
<div className={`text-lg font-bold ${metric.color} font-manrope`}>{metric.value}</div>
|
||||
<div className="text-white/60 text-xs font-manrope">{metric.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
249
components/vectors/QATestingVector.tsx
Normal file
249
components/vectors/QATestingVector.tsx
Normal file
@@ -0,0 +1,249 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const QATestingVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Testing Dashboard */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
<div className="w-72 h-48 bg-gradient-to-br from-gray-800 to-gray-900 rounded-lg shadow-2xl p-4">
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<div className="text-white font-semibold font-manrope">Test Results</div>
|
||||
<div className="flex space-x-1">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
|
||||
<div className="text-green-400 text-xs font-manrope">Running</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Test Cases */}
|
||||
<div className="space-y-2">
|
||||
{[
|
||||
{ name: "Login Flow", status: "passed", color: "green" },
|
||||
{ name: "Payment Gateway", status: "passed", color: "green" },
|
||||
{ name: "User Registration", status: "running", color: "yellow" },
|
||||
{ name: "API Validation", status: "passed", color: "green" },
|
||||
{ name: "Mobile Responsive", status: "failed", color: "red" }
|
||||
].map((test, index) => (
|
||||
<motion.div
|
||||
key={test.name}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.5, delay: index * 0.1 + 0.3 }}
|
||||
className="flex items-center justify-between p-2 bg-gray-700 rounded"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<motion.div
|
||||
animate={test.status === "running" ? { rotate: 360 } : {}}
|
||||
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
|
||||
className={`w-3 h-3 rounded-full ${
|
||||
test.color === "green" ? "bg-green-500" :
|
||||
test.color === "yellow" ? "bg-yellow-500" : "bg-red-500"
|
||||
}`}
|
||||
/>
|
||||
<span className="text-white text-sm font-manrope">{test.name}</span>
|
||||
</div>
|
||||
<span className={`text-xs font-manrope ${
|
||||
test.color === "green" ? "text-green-400" :
|
||||
test.color === "yellow" ? "text-yellow-400" : "text-red-400"
|
||||
}`}>
|
||||
{test.status}
|
||||
</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Statistics */}
|
||||
<div className="flex justify-between mt-4 pt-3 border-t border-gray-600">
|
||||
<div className="text-center">
|
||||
<div className="text-green-400 font-bold font-manrope">85%</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Passed</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-yellow-400 font-bold font-manrope">10%</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Running</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-red-400 font-bold font-manrope">5%</div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Failed</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Testing Tools */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="absolute left-8 top-1/2 transform -translate-y-1/2"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{/* Selenium */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-14 h-14 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">Selenium</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Cypress */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-14 h-14 bg-gradient-to-br from-gray-600 to-gray-700 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">Cypress</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Jest */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-14 h-14 bg-gradient-to-br from-red-500 to-red-600 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">Jest</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Bug Tracking */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
className="absolute right-8 top-16"
|
||||
>
|
||||
<div className="w-24 h-32 bg-gradient-to-br from-red-600 to-red-800 rounded-lg p-3 shadow-lg">
|
||||
<div className="text-white text-sm font-manrope mb-2">Bug Report</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-2 h-2 bg-red-400 rounded-full"></div>
|
||||
<span className="text-red-200 text-xs font-manrope">#001</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-2 h-2 bg-yellow-400 rounded-full"></div>
|
||||
<span className="text-yellow-200 text-xs font-manrope">#002</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-2 h-2 bg-green-400 rounded-full"></div>
|
||||
<span className="text-green-200 text-xs font-manrope">#003</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Performance Metrics */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8 }}
|
||||
className="absolute bottom-16 left-1/2 transform -translate-x-1/2"
|
||||
>
|
||||
<div className="flex space-x-6">
|
||||
{/* Load Time */}
|
||||
<div className="text-center">
|
||||
<motion.div
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.2 }}
|
||||
className="w-16 h-16 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full flex items-center justify-center mb-2"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">1.2s</span>
|
||||
</motion.div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Load Time</div>
|
||||
</div>
|
||||
|
||||
{/* Coverage */}
|
||||
<div className="text-center">
|
||||
<motion.div
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.4 }}
|
||||
className="w-16 h-16 bg-gradient-to-br from-green-500 to-green-600 rounded-full flex items-center justify-center mb-2"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">95%</span>
|
||||
</motion.div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Coverage</div>
|
||||
</div>
|
||||
|
||||
{/* Success Rate */}
|
||||
<div className="text-center">
|
||||
<motion.div
|
||||
initial={{ scale: 0 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 1.6 }}
|
||||
className="w-16 h-16 bg-gradient-to-br from-purple-500 to-purple-600 rounded-full flex items-center justify-center mb-2"
|
||||
>
|
||||
<span className="text-white text-xs font-manrope">99.2%</span>
|
||||
</motion.div>
|
||||
<div className="text-gray-400 text-xs font-manrope">Success</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Floating Test Icons */}
|
||||
<motion.div
|
||||
animate={{ y: [0, -10, 0] }}
|
||||
transition={{ duration: 3, repeat: Infinity }}
|
||||
className="absolute top-20 left-20 w-10 h-10 bg-gradient-to-br from-cyan-500 to-cyan-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<svg className="w-5 h-5 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
|
||||
animate={{ y: [0, -15, 0] }}
|
||||
transition={{ duration: 4, repeat: Infinity, delay: 0.5 }}
|
||||
className="absolute top-32 right-24 w-8 h-8 bg-gradient-to-br from-orange-500 to-orange-600 rounded-lg flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</motion.div>
|
||||
|
||||
{/* Test Automation Flow */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-30">
|
||||
<defs>
|
||||
<linearGradient id="testFlow" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#10B981" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#E5195E" stopOpacity="0.8" />
|
||||
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.6" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<motion.circle
|
||||
cx="50%" cy="50%" r="120"
|
||||
stroke="url(#testFlow)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="10,10"
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 15, repeat: Infinity, ease: "linear" }}
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Quality Labels */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 1.8 }}
|
||||
className="absolute bottom-8 right-8 flex flex-col space-y-1"
|
||||
>
|
||||
<div className="px-2 py-1 bg-green-500/20 text-green-300 border border-green-500/30 rounded text-xs font-manrope">
|
||||
Automated Testing
|
||||
</div>
|
||||
<div className="px-2 py-1 bg-blue-500/20 text-blue-300 border border-blue-500/30 rounded text-xs font-manrope">
|
||||
Performance Testing
|
||||
</div>
|
||||
<div className="px-2 py-1 bg-purple-500/20 text-purple-300 border border-purple-500/30 rounded text-xs font-manrope">
|
||||
Security Testing
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
123
components/vectors/TeamCollaborationVector.tsx
Normal file
123
components/vectors/TeamCollaborationVector.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
107
components/vectors/TechStackVisualization.tsx
Normal file
107
components/vectors/TechStackVisualization.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface TechStackVisualizationProps {
|
||||
stacks: Array<{
|
||||
name: string;
|
||||
technologies: string[];
|
||||
color: string;
|
||||
icon: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const TechStackVisualization = ({ stacks }: TechStackVisualizationProps) => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Central Hub */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative w-32 h-32 bg-gradient-to-br from-accent to-purple-600 rounded-full flex items-center justify-center z-10"
|
||||
>
|
||||
<div className="w-20 h-20 bg-white/20 rounded-full flex items-center justify-center backdrop-blur-sm">
|
||||
<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="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 9.172V5L8 4z" />
|
||||
</svg>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Tech Stack Orbits */}
|
||||
{stacks.map((stack, stackIndex) => (
|
||||
<motion.div
|
||||
key={stack.name}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6, delay: stackIndex * 0.3 }}
|
||||
className="absolute"
|
||||
>
|
||||
{/* Stack Hub */}
|
||||
<motion.div
|
||||
animate={{
|
||||
rotate: stackIndex % 2 === 0 ? 360 : -360
|
||||
}}
|
||||
transition={{
|
||||
duration: 20 + stackIndex * 5,
|
||||
repeat: Infinity,
|
||||
ease: "linear"
|
||||
}}
|
||||
className="relative"
|
||||
style={{
|
||||
transform: `rotate(${stackIndex * (360 / stacks.length)}deg) translateX(${120 + stackIndex * 20}px) rotate(-${stackIndex * (360 / stacks.length)}deg)`
|
||||
}}
|
||||
>
|
||||
<div className={`w-16 h-16 bg-gradient-to-br ${stack.color} rounded-full flex items-center justify-center shadow-lg`}>
|
||||
<span className="text-2xl">{stack.icon}</span>
|
||||
</div>
|
||||
|
||||
{/* Stack Label */}
|
||||
<div className="absolute -bottom-8 left-1/2 transform -translate-x-1/2 text-white text-xs font-manrope whitespace-nowrap">
|
||||
{stack.name}
|
||||
</div>
|
||||
|
||||
{/* Technologies around the stack */}
|
||||
{stack.technologies.map((tech, techIndex) => (
|
||||
<motion.div
|
||||
key={tech}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.4, delay: stackIndex * 0.3 + techIndex * 0.1 + 0.5 }}
|
||||
className="absolute w-8 h-8 bg-white/10 border border-white/20 rounded-full flex items-center justify-center text-xs font-manrope text-white backdrop-blur-sm"
|
||||
style={{
|
||||
transform: `rotate(${techIndex * (360 / stack.technologies.length)}deg) translateX(35px) rotate(-${techIndex * (360 / stack.technologies.length)}deg)`,
|
||||
fontSize: '8px'
|
||||
}}
|
||||
>
|
||||
{tech.slice(0, 2)}
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Animated Particles */}
|
||||
{Array.from({ length: 8 }).map((_, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
className="absolute w-2 h-2 bg-accent/60 rounded-full"
|
||||
animate={{
|
||||
x: [0, Math.random() * 400 - 200],
|
||||
y: [0, Math.random() * 400 - 200],
|
||||
opacity: [0, 1, 0],
|
||||
scale: [0, 1, 0]
|
||||
}}
|
||||
transition={{
|
||||
duration: 3 + Math.random() * 2,
|
||||
repeat: Infinity,
|
||||
delay: index * 0.5,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
style={{
|
||||
left: '50%',
|
||||
top: '50%'
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
276
components/vectors/UIUXVector.tsx
Normal file
276
components/vectors/UIUXVector.tsx
Normal file
@@ -0,0 +1,276 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export const UIUXVector = () => {
|
||||
return (
|
||||
<div className="relative w-full h-96 flex items-center justify-center">
|
||||
{/* Design Canvas */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
<div className="w-64 h-48 bg-gradient-to-br from-gray-800 to-gray-900 rounded-lg shadow-2xl p-4">
|
||||
{/* Figma Interface */}
|
||||
<div className="h-full bg-white rounded overflow-hidden relative">
|
||||
{/* Header */}
|
||||
<div className="h-6 bg-gray-100 flex items-center px-2 space-x-1">
|
||||
<div className="w-2 h-2 bg-red-500 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-yellow-500 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
|
||||
<div className="flex-1 text-center">
|
||||
<span className="text-gray-600 text-xs font-manrope">Design System</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Design Elements */}
|
||||
<div className="p-3 space-y-2">
|
||||
{/* Wireframe Elements */}
|
||||
<div className="flex space-x-2">
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "60%" }}
|
||||
transition={{ duration: 0.8, delay: 0.5 }}
|
||||
className="h-3 bg-gradient-to-r from-blue-400 to-blue-500 rounded"
|
||||
/>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "30%" }}
|
||||
transition={{ duration: 0.8, delay: 0.7 }}
|
||||
className="h-3 bg-accent rounded"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-1">
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ height: 0 }}
|
||||
animate={{ height: "12px" }}
|
||||
transition={{ duration: 0.5, delay: i * 0.1 + 0.9 }}
|
||||
className="flex-1 bg-gray-300 rounded"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Component Grid */}
|
||||
<div className="grid grid-cols-3 gap-1 mt-3">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ scale: 0, rotate: 180 }}
|
||||
animate={{ scale: 1, rotate: 0 }}
|
||||
transition={{ duration: 0.3, delay: i * 0.1 + 1.2 }}
|
||||
className="aspect-square bg-gradient-to-br from-purple-300 to-purple-400 rounded"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Design Tools Palette */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="absolute left-8 top-1/2 transform -translate-y-1/2"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
{/* Figma */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-12 h-12 bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 12a4 4 0 108 0 4 4 0 00-8 0z"/>
|
||||
<path d="M4 16a4 4 0 018 0v-4H8a4 4 0 00-4 4z"/>
|
||||
<path d="M4 8a4 4 0 014-4h4v8H8a4 4 0 01-4-4z"/>
|
||||
<path d="M12 4h4a4 4 0 010 8h-4V4z"/>
|
||||
</svg>
|
||||
</motion.div>
|
||||
|
||||
{/* Sketch */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-12 h-12 bg-gradient-to-br from-orange-500 to-orange-600 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white font-bold font-manrope">S</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Adobe XD */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-12 h-12 bg-gradient-to-br from-pink-500 to-pink-600 rounded-xl flex items-center justify-center shadow-lg cursor-pointer"
|
||||
>
|
||||
<span className="text-white font-bold font-manrope">Xd</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* User Journey Flow */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
className="absolute bottom-12 left-1/2 transform -translate-x-1/2"
|
||||
>
|
||||
<div className="flex items-center space-x-4">
|
||||
{/* User Persona */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<svg className="w-5 h-5 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>
|
||||
|
||||
{/* Flow Arrow */}
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "24px" }}
|
||||
transition={{ duration: 0.5, delay: 1.5 }}
|
||||
className="h-0.5 bg-gradient-to-r from-blue-500 to-purple-500"
|
||||
/>
|
||||
|
||||
{/* Wireframe */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-10 h-10 bg-gradient-to-br from-gray-500 to-gray-600 rounded border-2 border-gray-400 flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<div className="w-4 h-4 border border-gray-300 rounded-sm"></div>
|
||||
</motion.div>
|
||||
|
||||
{/* Flow Arrow */}
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: "24px" }}
|
||||
transition={{ duration: 0.5, delay: 1.7 }}
|
||||
className="h-0.5 bg-gradient-to-r from-gray-500 to-accent"
|
||||
/>
|
||||
|
||||
{/* Prototype */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.1 }}
|
||||
className="w-10 h-10 bg-gradient-to-br from-accent to-pink-600 rounded flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 18h.01M8 21h8a1 1 0 001-1V4a1 1 0 00-1-1H8a1 1 0 00-1 1v16a1 1 0 001 1z" />
|
||||
</svg>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between mt-2 text-xs text-gray-400 font-manrope">
|
||||
<span>Research</span>
|
||||
<span>Design</span>
|
||||
<span>Prototype</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Color Palette */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8 }}
|
||||
className="absolute right-8 top-16"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<div className="text-white text-sm font-manrope mb-2">Colors</div>
|
||||
<div className="flex space-x-1">
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.2 }}
|
||||
className="w-6 h-6 bg-blue-500 rounded cursor-pointer shadow-lg"
|
||||
/>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.2 }}
|
||||
className="w-6 h-6 bg-accent rounded cursor-pointer shadow-lg"
|
||||
/>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.2 }}
|
||||
className="w-6 h-6 bg-purple-500 rounded cursor-pointer shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Typography */}
|
||||
<div className="mt-4">
|
||||
<div className="text-white text-sm font-manrope mb-2">Typography</div>
|
||||
<div className="space-y-1">
|
||||
<div className="text-white text-lg font-manrope">Aa</div>
|
||||
<div className="text-gray-400 text-sm font-manrope">Manrope</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* User Testing Elements */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1, delay: 1.2 }}
|
||||
className="absolute top-8 left-16"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-8 h-8 bg-green-500 rounded-full flex items-center justify-center">
|
||||
<svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-green-400 text-sm font-manrope">Usability: 95%</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Accessibility Icon */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, rotate: -180 }}
|
||||
animate={{ opacity: 1, rotate: 0 }}
|
||||
transition={{ duration: 0.8, delay: 1.4 }}
|
||||
className="absolute top-12 right-32"
|
||||
>
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-teal-500 to-teal-600 rounded-full flex items-center justify-center shadow-lg">
|
||||
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Design System Components */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 1.6 }}
|
||||
className="absolute bottom-8 right-8 flex space-x-2"
|
||||
>
|
||||
<div className="px-2 py-1 bg-blue-500/20 text-blue-300 border border-blue-500/30 rounded text-xs font-manrope">
|
||||
Components
|
||||
</div>
|
||||
<div className="px-2 py-1 bg-purple-500/20 text-purple-300 border border-purple-500/30 rounded text-xs font-manrope">
|
||||
Design System
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Interactive Design Flow */}
|
||||
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-20">
|
||||
<defs>
|
||||
<linearGradient id="designFlow" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#8B5CF6" stopOpacity="0.6" />
|
||||
<stop offset="50%" stopColor="#E5195E" stopOpacity="0.8" />
|
||||
<stop offset="100%" stopColor="#3B82F6" stopOpacity="0.6" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<motion.path
|
||||
d="M 10% 80% Q 50% 20% 90% 80%"
|
||||
stroke="url(#designFlow)"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
initial={{ pathLength: 0 }}
|
||||
animate={{ pathLength: 1 }}
|
||||
transition={{ duration: 3, repeat: Infinity, repeatType: "reverse" }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
39
components/vectors/index.tsx
Normal file
39
components/vectors/index.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
// Vector Components for Hire Talent and Development Pages
|
||||
export { DeveloperSkillsVector } from './DeveloperSkillsVector';
|
||||
export { TeamCollaborationVector } from './TeamCollaborationVector';
|
||||
export { ProjectTimelineVector } from './ProjectTimelineVector';
|
||||
export { TechStackVisualization } from './TechStackVisualization';
|
||||
|
||||
// New page-specific vectors
|
||||
export { MobileAppVector } from './MobileAppVector';
|
||||
export { FullStackVector } from './FullStackVector';
|
||||
export { FrontendVector } from './FrontendVector';
|
||||
export { BackendVector } from './BackendVector';
|
||||
export { UIUXVector } from './UIUXVector';
|
||||
export { QATestingVector } from './QATestingVector';
|
||||
export { EngagementModelsVector } from './EngagementModelsVector';
|
||||
export { DashboardVector } from './DashboardVector';
|
||||
|
||||
// Vector Usage Guide:
|
||||
//
|
||||
// Each hire talent page now has its own custom vector component:
|
||||
// - HireMobileAppDevelopers -> MobileAppVector (mobile devices, cross-platform)
|
||||
// - HireFullStackDevelopers -> FullStackVector (frontend + backend integration)
|
||||
// - HireFrontendDevelopers -> FrontendVector (UI components, browser interface)
|
||||
// - HireBackendDevelopers -> BackendVector (servers, databases, APIs)
|
||||
// - HireUIUXDesigners -> UIUXVector (design tools, user journey)
|
||||
// - HireQAEngineers -> QATestingVector (testing dashboard, automation tools)
|
||||
// - DedicatedDevelopmentTeams -> TeamCollaborationVector (team interaction)
|
||||
// - EngagementModels -> EngagementModelsVector (business models, decision factors)
|
||||
// - TeamAugmentationServices -> DeveloperSkillsVector (skills augmentation)
|
||||
// - Default fallback -> DashboardVector (modern dashboard interface)
|
||||
//
|
||||
// To use vectors in HireTalentHeroBanner:
|
||||
// <HireTalentHeroBanner vectorComponent={MobileAppVector} ... />
|
||||
//
|
||||
// Vectors are designed to be:
|
||||
// - Responsive and scalable
|
||||
// - Consistent with WDI brand colors (#E5195E, gradients)
|
||||
// - Animated with Motion (Framer Motion)
|
||||
// - Accessible and semantic
|
||||
// - Performance optimized
|
||||
Reference in New Issue
Block a user