Skip to content

Instantly share code, notes, and snippets.

@developerfred
Created July 8, 2025 07:28
Show Gist options
  • Save developerfred/0163b901043fa16a9d24d4a2c6c61afa to your computer and use it in GitHub Desktop.
Save developerfred/0163b901043fa16a9d24d4a2c6c61afa to your computer and use it in GitHub Desktop.

Revisions

  1. developerfred created this gist Jul 8, 2025.
    217 changes: 217 additions & 0 deletions CourseSubscription.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,217 @@
    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;