"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> ); }