Spaces:
Sleeping
Sleeping
| import React from 'react'; | |
| import { motion } from 'framer-motion'; | |
| import { VideoProvider } from '@/types'; | |
| import { ZapIcon, BrainIcon, CheckIcon } from './Icons'; | |
| interface ProviderSelectProps { | |
| onSelect: (provider: VideoProvider) => void; | |
| } | |
| const providers = [ | |
| { | |
| id: 'kling' as VideoProvider, | |
| name: 'Kie API', | |
| subtitle: '(cheap use less credits)', | |
| description: 'High-quality video generation with advanced continuity. Perfect for professional UGC and talking head videos.', | |
| icon: ZapIcon, | |
| color: 'coral', | |
| features: [ | |
| 'Veo 3.1 Fast Model', | |
| 'Image-to-Video & Text-to-Video', | |
| 'Video Extension (Seamless)', | |
| 'GPT-4o Prompt Generation', | |
| '9:16 Portrait Format', | |
| 'Voice Type Selection', | |
| ], | |
| badge: 'Recommended', | |
| }, | |
| { | |
| id: 'replicate' as VideoProvider, | |
| name: 'Replicate API', | |
| subtitle: '(more credits, more expensive)', | |
| description: 'Access to diverse video generation models. Great for experimentation and unique creative styles.', | |
| icon: BrainIcon, | |
| color: 'electric', | |
| features: [ | |
| 'Multiple Model Options', | |
| 'Flexible Duration', | |
| 'Creative Styles', | |
| 'Cost Effective', | |
| 'API Simplicity', | |
| 'Community Models', | |
| ], | |
| badge: 'Flexible', | |
| }, | |
| ]; | |
| export const ProviderSelect: React.FC<ProviderSelectProps> = ({ onSelect }) => { | |
| return ( | |
| <div className="min-h-[70vh] flex flex-col items-center justify-center p-8"> | |
| {/* Hero Section */} | |
| <motion.div | |
| className="text-center mb-16" | |
| initial={{ opacity: 0, y: -20 }} | |
| animate={{ opacity: 1, y: 0 }} | |
| transition={{ duration: 0.6 }} | |
| > | |
| <h1 className="text-5xl md:text-6xl font-display font-bold mb-4"> | |
| <span className="gradient-text">Video AdGenesis</span> | |
| <span className="text-void-200"> Studio</span> | |
| </h1> | |
| <p className="text-xl text-void-400 max-w-2xl mx-auto"> | |
| Transform your scripts into stunning videos with AI. Choose your preferred generation engine to get started. | |
| </p> | |
| </motion.div> | |
| {/* Provider Cards */} | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-5xl w-full"> | |
| {providers.map((provider, index) => ( | |
| <motion.div | |
| key={provider.id} | |
| initial={{ opacity: 0, y: 30 }} | |
| animate={{ opacity: 1, y: 0 }} | |
| transition={{ duration: 0.5, delay: index * 0.15 }} | |
| > | |
| <button | |
| onClick={() => onSelect(provider.id)} | |
| className={` | |
| w-full text-left provider-card card-interactive | |
| ${provider.color === 'coral' ? 'hover:border-coral-500/50 hover:glow-coral' : 'hover:border-electric-500/50 hover:glow-electric'} | |
| group transition-all duration-500 | |
| `} | |
| > | |
| {/* Badge */} | |
| <div className="flex items-start justify-between mb-6"> | |
| <div className={` | |
| w-16 h-16 rounded-2xl flex items-center justify-center | |
| ${provider.color === 'coral' | |
| ? 'bg-coral-500/10 text-coral-400 group-hover:bg-coral-500/20' | |
| : 'bg-electric-500/10 text-electric-400 group-hover:bg-electric-500/20' | |
| } | |
| transition-colors duration-300 | |
| `}> | |
| <provider.icon size={32} /> | |
| </div> | |
| <span className={` | |
| px-3 py-1 rounded-full text-xs font-semibold | |
| ${provider.color === 'coral' | |
| ? 'bg-coral-500/20 text-coral-300' | |
| : 'bg-electric-500/20 text-electric-300' | |
| } | |
| `}> | |
| {provider.badge} | |
| </span> | |
| </div> | |
| {/* Title & Description */} | |
| <h2 className="text-2xl font-display font-bold text-void-100 mb-1"> | |
| {provider.name} | |
| </h2> | |
| <p className={`text-sm mb-3 ${provider.color === 'coral' ? 'text-coral-400' : 'text-electric-400'}`}> | |
| {provider.subtitle} | |
| </p> | |
| <p className="text-void-400 text-sm mb-6 leading-relaxed"> | |
| {provider.description} | |
| </p> | |
| {/* Features */} | |
| <div className="grid grid-cols-2 gap-2"> | |
| {provider.features.map((feature, i) => ( | |
| <div key={i} className="flex items-center gap-2"> | |
| <CheckIcon | |
| size={14} | |
| className={provider.color === 'coral' ? 'text-coral-400' : 'text-electric-400'} | |
| /> | |
| <span className="text-xs text-void-300">{feature}</span> | |
| </div> | |
| ))} | |
| </div> | |
| {/* CTA Arrow */} | |
| <div className={` | |
| mt-6 flex items-center gap-2 text-sm font-semibold | |
| ${provider.color === 'coral' ? 'text-coral-400' : 'text-electric-400'} | |
| group-hover:gap-4 transition-all duration-300 | |
| `}> | |
| <span>Get Started</span> | |
| <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" /> | |
| </svg> | |
| </div> | |
| </button> | |
| </motion.div> | |
| ))} | |
| </div> | |
| {/* Footer Note */} | |
| <motion.p | |
| className="mt-12 text-void-500 text-sm text-center" | |
| initial={{ opacity: 0 }} | |
| animate={{ opacity: 1 }} | |
| transition={{ delay: 0.8 }} | |
| > | |
| Both providers use your Python backend. API keys are configured server-side. | |
| </motion.p> | |
| </div> | |
| ); | |
| }; | |