2025-02-16 19:49:16 +05:30

523 lines
18 KiB
TypeScript

"use client";
import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
const VectorNoCode = () => {
const [step, setStep] = useState(0);
const nodes = [
{
icon: (
<svg className="w-6 h-6 text-purple-200" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<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>
),
label: "Input"
},
{
icon: (
<svg className="w-6 h-6 text-purple-200" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<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 10.172V5L8 4z" />
</svg>
),
label: "Process"
},
{
icon: (
<svg className="w-6 h-6 text-purple-200" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
),
label: "Output"
}
];
useEffect(() => {
const timer = setTimeout(() => {
setStep((prev) => (prev + 1) % 3);
}, 3000);
return () => clearTimeout(timer);
}, [step]);
return (
<motion.div className="w-full h-[400px] bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 relative overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center">
{nodes.map((node, i) => (
<motion.div
key={i}
className="absolute"
initial={{ x: -200 + i * 200 }}
>
{/* Node container */}
<motion.div
className="relative flex flex-col items-center"
animate={{
scale: step >= i ? 1.1 : 1,
opacity: step >= i ? 1 : 0.5,
}}
transition={{
duration: 0.5,
type: "spring",
}}
>
{/* Node */}
<motion.div
className="w-16 h-16 rounded-xl bg-gradient-to-br from-purple-500/30 to-blue-500/30
flex items-center justify-center backdrop-blur-sm"
animate={{
scale: step === i ? [1, 1.2, 1] : 1,
backgroundColor: step >= i ? "rgba(139, 92, 246, 0.4)" : "rgba(139, 92, 246, 0.2)"
}}
transition={{ duration: 0.5 }}
>
{node.icon}
</motion.div>
{/* Label */}
<motion.span
className="mt-2 text-sm text-purple-200"
animate={{
opacity: step >= i ? 1 : 0.5
}}
>
{node.label}
</motion.span>
</motion.div>
{/* Connection line */}
{i < 2 && (
<motion.div
className="absolute w-[200px] h-[2px] bg-gradient-to-r from-purple-500/30 to-blue-500/30 left-16 top-8"
initial={{ scaleX: 0 }}
animate={{
scaleX: step > i ? 1 : 0,
}}
transition={{
duration: 1,
ease: "easeInOut"
}}
>
{/* Moving dot */}
<motion.div
className="absolute h-4 w-4 bg-purple-500/50 rounded-full -translate-y-[6px]"
initial={{ x: 0, opacity: 0 }}
animate={{
x: step > i ? [0, 200] : 0,
opacity: step > i ? [1, 0] : 0,
scale: step > i ? [1, 1.5, 1] : 1
}}
transition={{
duration: 1,
ease: "easeInOut"
}}
/>
</motion.div>
)}
</motion.div>
))}
</div>
</motion.div>
);
};
const VectorCreativeSuite = () => (
<motion.div className="w-full h-[400px] bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 relative overflow-hidden">
<div className="flex h-full gap-4">
{/* Editor Panel */}
<div className="flex-1 bg-black/20 rounded-xl p-4">
<div className="flex items-center gap-2 mb-4">
<motion.div
className="w-3 h-3 rounded-full bg-red-500/70"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, repeat: Infinity }}
/>
<motion.div
className="w-3 h-3 rounded-full bg-yellow-500/70"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, delay: 0.3, repeat: Infinity }}
/>
<motion.div
className="w-3 h-3 rounded-full bg-green-500/70"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, delay: 0.6, repeat: Infinity }}
/>
</div>
<motion.div
className="h-4 w-32 bg-purple-500/30 rounded-md mb-4"
animate={{ width: ["8rem", "12rem", "8rem"] }}
transition={{ duration: 3, repeat: Infinity }}
/>
<div className="space-y-2">
{[...Array(5)].map((_, i) => (
<motion.div
key={i}
className="h-3 bg-purple-500/20 rounded"
initial={{ width: "40%" }}
animate={{ width: ["40%", "100%", "40%"] }}
transition={{
duration: 4,
delay: i * 0.2,
repeat: Infinity,
}}
/>
))}
</div>
</div>
{/* Preview Panel */}
<div className="flex-1 bg-black/20 rounded-xl p-4">
<motion.div
className="w-full h-full rounded-lg bg-gradient-to-br from-purple-500/20 to-blue-500/20 relative"
animate={{
boxShadow: [
"0 0 0 0 rgba(139, 92, 246, 0)",
"0 0 20px 2px rgba(139, 92, 246, 0.3)",
"0 0 0 0 rgba(139, 92, 246, 0)"
]
}}
transition={{ duration: 3, repeat: Infinity }}
>
<motion.div
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-16 h-16 border-4 border-purple-500/30 rounded-full border-t-transparent"
animate={{ rotate: 360 }}
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
/>
<motion.div
className="absolute bottom-4 left-1/2 -translate-x-1/2 h-2 w-24 bg-purple-500/30 rounded-full"
animate={{ width: ["6rem", "8rem", "6rem"] }}
transition={{ duration: 2, repeat: Infinity }}
/>
</motion.div>
</div>
</div>
</motion.div>
);
const VectorCommunity = () => {
// Reduced number of points
const gridPoints = Array.from({ length: 15 }, (_, i) => ({
id: i,
x: (i % 5) * 100 + 80,
y: Math.floor(i / 5) * 100 + 80,
}));
return (
<motion.div className="w-full h-[400px] bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 relative overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center">
{/* Connection lines */}
<svg className="absolute w-full h-full">
{gridPoints.map((point, i) => (
gridPoints.slice(i + 1).map((target, j) => {
const distance = Math.sqrt(
Math.pow(point.x - target.x, 2) +
Math.pow(point.y - target.y, 2)
);
// Increased connection distance for wider coverage
if (distance < 240) { // Increased distance to maintain connections
return (
<motion.line
key={`${i}-${j}`}
x1={point.x}
y1={point.y}
x2={target.x}
y2={target.y}
stroke="rgba(139, 92, 246, 0.2)"
strokeWidth="1"
initial={{ opacity: 0 }}
animate={{
opacity: [0.2, 0.5, 0.2],
strokeWidth: [1, 2, 1]
}}
transition={{
duration: 2,
delay: (i + j) * 0.1,
repeat: Infinity
}}
/>
);
}
return null;
})
))}
</svg>
{/* User icons */}
{gridPoints.map((point, i) => (
<motion.div
key={i}
className="absolute"
style={{
left: point.x,
top: point.y,
transform: 'translate(-50%, -50%)'
}}
initial={{ scale: 0 }}
animate={{
scale: [1, 1.2, 1],
y: [0, -5, 0]
}}
transition={{
duration: 3,
delay: i * 0.1,
repeat: Infinity,
repeatType: "reverse"
}}
>
<div className="w-8 h-8 rounded-full bg-purple-500/30 flex items-center justify-center">
<svg
className="w-4 h-4 text-purple-200"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
>
<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>
</div>
<motion.div
className="absolute -top-1 -right-1 w-2 h-2 rounded-full bg-green-400"
animate={{
scale: [1, 1.5, 1],
opacity: [0.5, 1, 0.5]
}}
transition={{
duration: 2,
delay: i * 0.2,
repeat: Infinity
}}
/>
</motion.div>
))}
{/* Central hub - made larger */}
<motion.div
className="absolute w-16 h-16 rounded-full bg-purple-600/40 flex items-center justify-center"
animate={{
scale: [1, 1.2, 1],
boxShadow: [
"0 0 0 0 rgba(139, 92, 246, 0.4)",
"0 0 20px 10px rgba(139, 92, 246, 0.2)",
"0 0 0 0 rgba(139, 92, 246, 0.4)"
]
}}
transition={{
duration: 3,
repeat: Infinity
}}
>
<svg
className="w-8 h-8 text-purple-200"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
/>
</svg>
</motion.div>
</div>
</motion.div>
);
};
const VectorMonetization = () => {
const subscriptionTiers = [
{ name: "Basic", price: "49", color: "from-blue-500/30 to-purple-500/30" },
{ name: "Pro", price: "199", color: "from-purple-500/30 to-pink-500/30" },
{ name: "Enterprise", price: "499", color: "from-pink-500/30 to-orange-500/30" }
];
return (
<motion.div className="w-full h-[400px] bg-gradient-to-br from-purple-900/20 to-blue-900/20 rounded-xl p-6 relative overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center">
<div className="relative w-full h-full flex items-center justify-center">
{/* Background rings */}
{[...Array(3)].map((_, i) => (
<motion.div
key={i}
className="absolute rounded-full border-2 border-purple-500/20"
style={{
width: `${(i + 1) * 150}px`,
height: `${(i + 1) * 150}px`,
}}
animate={{
rotate: 360,
scale: [1, 1.05, 1],
}}
transition={{
rotate: {
duration: 10 + i * 5,
repeat: Infinity,
ease: "linear",
},
scale: {
duration: 2,
repeat: Infinity,
delay: i * 0.3,
}
}}
/>
))}
{/* Subscription tiers */}
{subscriptionTiers.map((tier, i) => (
<motion.div
key={i}
className={`absolute bg-gradient-to-br ${tier.color} rounded-xl p-4 backdrop-blur-sm
flex flex-col items-center justify-center w-32 h-32`}
style={{
x: i * 140 - 140,
y: 0,
}}
animate={{
y: [0, -20, 0],
scale: [1, 1.05, 1],
}}
transition={{
duration: 3,
delay: i * 0.2,
repeat: Infinity,
}}
whileHover={{ scale: 1.1 }}
>
<motion.span
className="text-sm text-purple-200 mb-2"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, repeat: Infinity }}
>
{tier.name}
</motion.span>
<motion.div
className="text-2xl font-bold text-white mb-1"
animate={{ scale: [1, 1.1, 1] }}
transition={{ duration: 2, repeat: Infinity }}
>
${tier.price}
</motion.div>
<motion.div
className="text-xs text-purple-200"
animate={{ opacity: [0.5, 1, 0.5] }}
transition={{ duration: 2, repeat: Infinity }}
>
per month
</motion.div>
</motion.div>
))}
{/* Floating elements */}
{[...Array(5)].map((_, i) => (
<motion.div
key={i}
className="absolute w-3 h-3"
style={{
x: Math.random() * 400 - 200,
y: Math.random() * 400 - 200,
}}
animate={{
y: [0, -100],
opacity: [0, 1, 0],
scale: [1, 1.5, 1],
}}
transition={{
duration: 2,
delay: i * 0.3,
repeat: Infinity,
}}
>
<div className="w-full h-full rounded-full bg-green-400/30" />
</motion.div>
))}
</div>
</div>
</motion.div>
);
};
const defaultFeaturesData = [
{
title: "No-Code AI Builder",
description: "Design, test, and deploy AI agents effortlessly. Create powerful AI applications without any coding knowledge required.",
vector: <VectorNoCode />,
},
{
title: "Creative Suite",
description: "Access powerful forms, video editing, and content creation tools to bring your vision to life. Transform your ideas into polished, professional content.",
vector: <VectorCreativeSuite />,
},
{
title: "Community & Marketplace",
description: "Grow your audience on your own platform or join our marketplace to reach thousands of SMBs. Build and nurture your community while expanding your reach.",
vector: <VectorCommunity />,
},
{
title: "Subscription-Based Monetization",
description: "Generate recurring revenue with our seamless subscription integration. Turn your AI solutions into a sustainable business model.",
vector: <VectorMonetization />,
},
];
interface Feature {
title: string;
description: string;
vector: React.ReactNode;
}
export default function Features({ featuresData }: { featuresData?: Feature[] }) {
const dataToUse = featuresData || defaultFeaturesData;
return (
<div className="container mx-auto p-6 py-40 text-white">
<motion.h2
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
viewport={{ once: true }}
className="text-4xl md:text-5xl text-center mb-16"
>
Everything You Need to Create, Manage, and Monetize Your AI Offerings
</motion.h2>
<div className="space-y-32"> {/* Increased spacing between features */}
{dataToUse.map((feature, index) => (
<motion.div
key={index}
initial={{ opacity: 0, x: index % 2 === 0 ? -100 : 100 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5 }}
viewport={{ once: true }}
className={`flex flex-col md:flex-row items-center gap-8 ${index % 2 === 0 ? '' : 'md:flex-row-reverse'}`}
>
<div className={`flex-1 ${index % 2 === 0 ? 'md:pr-8' : 'md:pl-8'}`}>
<div className={`space-y-6 ${index % 2 === 0 ? '' : 'text-right'}`}>
<h3 className="text-3xl md:text-5xl">{feature.title}</h3>
<p className="text-gray-400 text-lg">{feature.description}</p>
<motion.button
className="bg-purple-600 px-6 py-3 rounded-full hover:bg-purple-700 transition-colors"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Learn More
</motion.button>
</div>
</div>
<div className="w-full md:w-1/2">
{feature.vector}
</div>
</motion.div>
))}
</div>
</div>
);
}