Created
July 8, 2025 07:28
-
-
Save developerfred/0163b901043fa16a9d24d4a2c6c61afa to your computer and use it in GitHub Desktop.
Course Subscription Component - https://x.com/codingsh/status/1942485407892914681
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from 'react'; | |
import { Heart, Star, Users, Clock, BookOpen, CheckCircle } from 'lucide-react'; | |
const CourseSubscription = () => { | |
const [selectedAmount, setSelectedAmount] = useState(29); | |
const [isAnimating, setIsAnimating] = useState(false); | |
const [showSuccess, setShowSuccess] = useState(false); | |
const suggestedPrice = 29; | |
const maxPrice = 100; | |
const handleAmountChange = (value) => { | |
setSelectedAmount(value); | |
setIsAnimating(true); | |
setTimeout(() => setIsAnimating(false), 200); | |
}; | |
const handleSubscribe = () => { | |
setShowSuccess(true); | |
setTimeout(() => setShowSuccess(false), 3000); | |
}; | |
const getSliderColor = () => { | |
if (selectedAmount === 0) return 'from-green-500 to-green-600'; | |
if (selectedAmount < suggestedPrice) return 'from-orange-400 to-orange-500'; | |
return 'from-orange-500 to-red-500'; | |
}; | |
const getButtonText = () => { | |
if (selectedAmount === 0) return 'Acessar Gratuitamente'; | |
return `Assinar por R$ ${selectedAmount}`; | |
}; | |
const getMotivationalText = () => { | |
if (selectedAmount === 0) return 'Acesso gratuito disponível! 🎉'; | |
if (selectedAmount < suggestedPrice) return 'Obrigado pelo seu apoio! 💛'; | |
if (selectedAmount === suggestedPrice) return 'Valor sugerido - Perfeito! ⭐'; | |
return 'Você é incrível! Muito obrigado! 🚀'; | |
}; | |
return ( | |
<div className="min-h-screen bg-gradient-to-br from-gray-50 via-orange-50 to-gray-100 flex items-center justify-center p-4"> | |
<div className="max-w-md w-full"> | |
{/* Card Principal */} | |
<div className="bg-white/90 backdrop-blur-xl rounded-3xl p-8 shadow-2xl border border-gray-200/50"> | |
{/* Header do Curso */} | |
<div className="text-center mb-8"> | |
<div className="w-16 h-16 bg-gradient-to-r from-orange-500 to-red-500 rounded-2xl flex items-center justify-center mx-auto mb-4"> | |
<BookOpen className="w-8 h-8 text-white" /> | |
</div> | |
<h2 className="text-2xl font-bold text-gray-900 mb-2"> | |
Curso Completo Papi Simulator | |
</h2> | |
<p className="text-gray-600 text-sm"> | |
Aprenda a explorar o mundo da Polkadot | |
</p> | |
</div> | |
{/* Estatísticas do Curso */} | |
<div className="grid grid-cols-3 gap-4 mb-8"> | |
<div className="text-center"> | |
<div className="flex items-center justify-center mb-1"> | |
<Users className="w-4 h-4 text-orange-500" /> | |
</div> | |
<div className="text-gray-900 text-sm font-semibold">2.5k+</div> | |
<div className="text-gray-500 text-xs">Alunos</div> | |
</div> | |
<div className="text-center"> | |
<div className="flex items-center justify-center mb-1"> | |
<Clock className="w-4 h-4 text-orange-500" /> | |
</div> | |
<div className="text-gray-900 text-sm font-semibold">15h</div> | |
<div className="text-gray-500 text-xs">Conteúdo</div> | |
</div> | |
<div className="text-center"> | |
<div className="flex items-center justify-center mb-1"> | |
<Star className="w-4 h-4 text-orange-500" /> | |
</div> | |
<div className="text-gray-900 text-sm font-semibold">4.9</div> | |
<div className="text-gray-500 text-xs">Avaliação</div> | |
</div> | |
</div> | |
{/* Seção de Preço */} | |
<div className="mb-8"> | |
<div className="text-center mb-6"> | |
<div className="text-gray-600 text-sm mb-2"> | |
Quanto você gostaria de contribuir? | |
</div> | |
<div className={`text-4xl font-bold text-gray-900 transition-all duration-200 ${isAnimating ? 'scale-110' : 'scale-100'}`}> | |
{selectedAmount === 0 ? 'Grátis' : `R$ ${selectedAmount}`} | |
</div> | |
<div className="text-gray-400 text-xs mt-1"> | |
Sugerido: R$ {suggestedPrice} | |
</div> | |
</div> | |
{/* Slider Personalizado */} | |
<div className="mb-6"> | |
<div className="relative"> | |
<input | |
type="range" | |
min="0" | |
max={maxPrice} | |
value={selectedAmount} | |
onChange={(e) => handleAmountChange(parseInt(e.target.value))} | |
className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider" | |
style={{ | |
background: `linear-gradient(to right, rgb(249, 115, 22) 0%, rgb(239, 68, 68) ${(selectedAmount / maxPrice) * 100}%, rgb(229, 231, 235) ${(selectedAmount / maxPrice) * 100}%, rgb(229, 231, 235) 100%)` | |
}} | |
/> | |
<div className="flex justify-between mt-2 text-xs text-gray-400"> | |
<span>R$ 0</span> | |
<span>R$ {maxPrice}</span> | |
</div> | |
</div> | |
</div> | |
{/* Valores Rápidos */} | |
<div className="grid grid-cols-4 gap-2 mb-6"> | |
{[0, 15, 29, 50].map((amount) => ( | |
<button | |
key={amount} | |
onClick={() => handleAmountChange(amount)} | |
className={`py-2 px-3 rounded-lg text-sm font-medium transition-all duration-200 ${ | |
selectedAmount === amount | |
? 'bg-gradient-to-r from-orange-500 to-red-500 text-white shadow-lg scale-105' | |
: 'bg-gray-100 text-gray-600 hover:bg-gray-200' | |
}`} | |
> | |
{amount === 0 ? 'Grátis' : `R$ ${amount}`} | |
</button> | |
))} | |
</div> | |
{/* Texto Motivacional */} | |
<div className="text-center mb-6"> | |
<div className={`text-sm font-medium transition-all duration-300 ${ | |
selectedAmount === 0 ? 'text-green-500' : | |
selectedAmount < suggestedPrice ? 'text-orange-500' : | |
selectedAmount === suggestedPrice ? 'text-orange-600' : | |
'text-red-500' | |
}`}> | |
{getMotivationalText()} | |
</div> | |
</div> | |
</div> | |
{/* Botão de Assinatura */} | |
<button | |
onClick={handleSubscribe} | |
disabled={showSuccess} | |
className={`w-full py-4 px-6 rounded-2xl font-bold text-white transition-all duration-300 transform hover:scale-105 active:scale-95 ${ | |
showSuccess | |
? 'bg-green-500 shadow-lg shadow-green-500/25' | |
: `bg-gradient-to-r ${getSliderColor()} shadow-lg hover:shadow-xl` | |
}`} | |
> | |
{showSuccess ? ( | |
<div className="flex items-center justify-center"> | |
<CheckCircle className="w-5 h-5 mr-2" /> | |
Inscrição Confirmada! | |
</div> | |
) : ( | |
getButtonText() | |
)} | |
</button> | |
{/* Benefícios */} | |
<div className="mt-6 text-center"> | |
<div className="text-gray-400 text-xs mb-2"> | |
✓ Acesso vitalício • ✓ Certificado • ✓ Suporte da comunidade | |
</div> | |
</div> | |
</div> | |
{/* Mensagem de Apoio */} | |
<div className="mt-6 text-center"> | |
<div className="flex items-center justify-center text-gray-500 text-sm"> | |
<Heart className="w-4 h-4 mr-2 text-orange-500" /> | |
Este curso é feito com amor para a comunidade | |
</div> | |
</div> | |
</div> | |
<style jsx>{` | |
.slider::-webkit-slider-thumb { | |
appearance: none; | |
width: 20px; | |
height: 20px; | |
border-radius: 50%; | |
background: linear-gradient(45deg, #3b82f6, #8b5cf6); | |
cursor: pointer; | |
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4); | |
transition: all 0.2s ease; | |
} | |
.slider::-webkit-slider-thumb:hover { | |
transform: scale(1.1); | |
box-shadow: 0 6px 20px rgba(249, 115, 22, 0.6); | |
} | |
.slider::-moz-range-thumb { | |
width: 20px; | |
height: 20px; | |
border-radius: 50%; | |
background: linear-gradient(45deg, #3b82f6, #8b5cf6); | |
cursor: pointer; | |
border: none; | |
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4); | |
} | |
`}</style> | |
</div> | |
); | |
}; | |
export default CourseSubscription; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment