Spaces:
Sleeping
Sleeping
File size: 5,851 Bytes
91d209c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
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>
);
};
|