Spaces:
Running
Running
| -- Database schema for Monthly Tombola website | |
| CREATE DATABASE IF NOT EXISTS monthly_tombola; | |
| USE monthly_tombola; | |
| -- Users table to store participant information | |
| CREATE TABLE users ( | |
| user_id INT AUTO_INCREMENT PRIMARY KEY, | |
| email VARCHAR(255) NOT NULL UNIQUE, | |
| first_name VARCHAR(100), | |
| last_name VARCHAR(100), | |
| phone VARCHAR(20), | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| is_verified BOOLEAN DEFAULT FALSE, | |
| verification_token VARCHAR(255) | |
| ) ENGINE=InnoDB; | |
| -- Draws table to store each monthly draw information | |
| CREATE TABLE draws ( | |
| draw_id INT AUTO_INCREMENT PRIMARY KEY, | |
| draw_date DATE NOT NULL, | |
| prize_pot DECIMAL(12,2) DEFAULT 0.00, | |
| ticket_price DECIMAL(6,2) NOT NULL DEFAULT 10.00, | |
| is_completed BOOLEAN DEFAULT FALSE, | |
| completed_at TIMESTAMP NULL, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | |
| ) ENGINE=InnoDB; | |
| -- Tickets table to track all purchased tickets | |
| CREATE TABLE tickets ( | |
| ticket_id INT AUTO_INCREMENT PRIMARY KEY, | |
| draw_id INT NOT NULL, | |
| user_id INT NOT NULL, | |
| ticket_number VARCHAR(20) NOT NULL, | |
| purchase_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| payment_id INT, | |
| FOREIGN KEY (draw_id) REFERENCES draws(draw_id), | |
| FOREIGN KEY (user_id) REFERENCES users(user_id), | |
| INDEX (ticket_number), | |
| INDEX (draw_id, user_id) | |
| ) ENGINE=InnoDB; | |
| -- Payments table to track all transactions | |
| CREATE TABLE payments ( | |
| payment_id INT AUTO_INCREMENT PRIMARY KEY, | |
| user_id INT NOT NULL, | |
| amount DECIMAL(12,2) NOT NULL, | |
| currency VARCHAR(3) DEFAULT 'USD', | |
| payment_method ENUM('stripe', 'paypal', 'other') NOT NULL, | |
| transaction_id VARCHAR(255), | |
| status ENUM('pending', 'completed', 'failed', 'refunded') DEFAULT 'pending', | |
| payment_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(user_id), | |
| INDEX (transaction_id), | |
| INDEX (user_id, status) | |
| ) ENGINE=InnoDB; | |
| -- Winners table to store draw winners | |
| CREATE TABLE winners ( | |
| winner_id INT AUTO_INCREMENT PRIMARY KEY, | |
| draw_id INT NOT NULL, | |
| user_id INT NOT NULL, | |
| ticket_id INT NOT NULL, | |
| prize_amount DECIMAL(12,2) NOT NULL, | |
| claimed BOOLEAN DEFAULT FALSE, | |
| claimed_at TIMESTAMP NULL, | |
| payment_method VARCHAR(50), | |
| payment_details TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| FOREIGN KEY (draw_id) REFERENCES draws(draw_id), | |
| FOREIGN KEY (user_id) REFERENCES users(user_id), | |
| FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id), | |
| INDEX (draw_id, user_id) | |
| ) ENGINE=InnoDB; | |
| -- User sessions table | |
| CREATE TABLE user_sessions ( | |
| session_id VARCHAR(255) PRIMARY KEY, | |
| user_id INT NOT NULL, | |
| ip_address VARCHAR(45), | |
| user_agent TEXT, | |
| expires_at TIMESTAMP NOT NULL, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(user_id), | |
| INDEX (user_id, expires_at) | |
| ) ENGINE=InnoDB; | |
| -- Audit log for important actions | |
| CREATE TABLE audit_log ( | |
| log_id INT AUTO_INCREMENT PRIMARY KEY, | |
| user_id INT, | |
| action VARCHAR(50) NOT NULL, | |
| description TEXT, | |
| ip_address VARCHAR(45), | |
| user_agent TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(user_id) | |
| ) ENGINE=InnoDB; | |
| -- Payment methods table | |
| CREATE TABLE payment_methods ( | |
| method_id INT AUTO_INCREMENT PRIMARY KEY, | |
| user_id INT NOT NULL, | |
| method_type ENUM('card', 'paypal', 'bank') NOT NULL, | |
| details JSON, | |
| is_default BOOLEAN DEFAULT FALSE, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(user_id), | |
| INDEX (user_id, method_type) | |
| ) ENGINE=InnoDB; | |
| -- Add initial data (current month's draw) | |
| INSERT INTO draws (draw_date, ticket_price) | |
| VALUES (LAST_DAY(CURRENT_DATE()), 10.00); | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Monthly Tombola - Win Big Every Month!</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://js.stripe.com/v3/"></script> | |
| <script src="https://www.paypal.com/sdk/js?client-id=test¤cy=USD"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .ticket { | |
| perspective: 1000px; | |
| } | |
| .ticket-inner { | |
| transition: transform 0.6s; | |
| transform-style: preserve-3d; | |
| } | |
| .ticket:hover .ticket-inner { | |
| transform: rotateY(180deg); | |
| } | |
| .ticket-front, .ticket-back { | |
| backface-visibility: hidden; | |
| } | |
| .ticket-back { | |
| transform: rotateY(180deg); | |
| } | |
| .countdown-number { | |
| animation: pulse 1s infinite alternate; | |
| } | |
| @keyframes pulse { | |
| from { transform: scale(1); } | |
| to { transform: scale(1.05); } | |
| } | |
| .winner-badge { | |
| animation: glow 2s infinite alternate; | |
| } | |
| @keyframes glow { | |
| from { box-shadow: 0 0 5px #f59e0b; } | |
| to { box-shadow: 0 0 20px #f59e0b; } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gradient-to-b from-purple-900 to-indigo-900 text-white min-h-screen"> | |
| <!-- Navigation --> | |
| <nav class="bg-black bg-opacity-80 py-4 sticky top-0 z-50"> | |
| <div class="container mx-auto px-4 flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-trophy text-yellow-400 text-2xl"></i> | |
| <h1 class="text-2xl font-bold">Monthly<span class="text-yellow-400">Tombola</span></h1> | |
| </div> | |
| <div class="hidden md:flex space-x-6"> | |
| <a href="#how-it-works" class="hover:text-yellow-400 transition">How It Works</a> | |
| <a href="#current-draw" class="hover:text-yellow-400 transition">Current Draw</a> | |
| <a href="#previous-winners" class="hover:text-yellow-400 transition">Winners</a> | |
| <a href="#buy-tickets" class="hover:text-yellow-400 transition">Buy Tickets</a> | |
| </div> | |
| <button class="md:hidden text-2xl" id="mobile-menu-button"> | |
| <i class="fas fa-bars"></i> | |
| </button> | |
| </div> | |
| <div class="md:hidden hidden bg-black bg-opacity-90 py-2 px-4" id="mobile-menu"> | |
| <a href="#how-it-works" class="block py-2 hover:text-yellow-400 transition">How It Works</a> | |
| <a href="#current-draw" class="block py-2 hover:text-yellow-400 transition">Current Draw</a> | |
| <a href="#previous-winners" class="block py-2 hover:text-yellow-400 transition">Winners</a> | |
| <a href="#buy-tickets" class="block py-2 hover:text-yellow-400 transition">Buy Tickets</a> | |
| </div> | |
| </nav> | |
| <!-- Hero Section --> | |
| <section class="py-16 px-4 text-center"> | |
| <div class="max-w-4xl mx-auto"> | |
| <div class="bg-yellow-500 text-black font-bold py-1 px-4 rounded-full inline-block mb-4"> | |
| <i class="fas fa-star mr-2"></i>Next Draw: <span id="countdown" class="ml-1"></span> | |
| </div> | |
| <h1 class="text-4xl md:text-6xl font-bold mb-6">Win <span class="text-yellow-400">80%</span> of the Pot Every Month!</h1> | |
| <p class="text-xl mb-8 max-w-2xl mx-auto">Buy your tickets now for a chance to win the monthly prize. 80% goes to the winner, 20% is our commission.</p> | |
| <div class="flex flex-col sm:flex-row justify-center gap-4"> | |
| <a href="#buy-tickets" class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-8 rounded-full transition flex items-center justify-center"> | |
| <i class="fas fa-ticket-alt mr-2"></i> Buy Tickets Now | |
| </a> | |
| <a href="#how-it-works" class="bg-transparent hover:bg-white hover:bg-opacity-10 border-2 border-white py-3 px-8 rounded-full transition flex items-center justify-center"> | |
| <i class="fas fa-question-circle mr-2"></i> How It Works | |
| </a> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Current Pot --> | |
| <section id="current-draw" class="py-12 px-4 bg-black bg-opacity-30"> | |
| <div class="max-w-6xl mx-auto"> | |
| <h2 class="text-3xl font-bold mb-8 text-center">Current Monthly Draw</h2> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <div class="bg-indigo-800 bg-opacity-50 p-6 rounded-xl text-center"> | |
| <div class="text-5xl font-bold text-yellow-400 mb-2">$<span id="current-pot">5,420</span></div> | |
| <div class="text-xl">Current Prize Pot</div> | |
| <div class="mt-4 text-sm opacity-80">80% to winner (≈ $<span id="winner-portion">4,336</span>)</div> | |
| </div> | |
| <div class="bg-indigo-800 bg-opacity-50 p-6 rounded-xl text-center"> | |
| <div class="text-5xl font-bold text-yellow-400 mb-2"><span id="tickets-sold">542</span></div> | |
| <div class="text-xl">Tickets Sold</div> | |
| <div class="mt-4 text-sm opacity-80">$10 per ticket</div> | |
| </div> | |
| <div class="bg-indigo-800 bg-opacity-50 p-6 rounded-xl text-center"> | |
| <div class="text-5xl font-bold text-yellow-400 mb-2"><span id="days-left">14</span></div> | |
| <div class="text-xl">Days Remaining</div> | |
| <div class="mt-4 text-sm opacity-80">Draw on <span id="draw-date">June 30, 2023</span></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- How It Works --> | |
| <section id="how-it-works" class="py-16 px-4"> | |
| <div class="max-w-4xl mx-auto"> | |
| <h2 class="text-3xl font-bold mb-12 text-center">How It Works</h2> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <div class="text-center"> | |
| <div class="bg-yellow-500 text-black w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">1</div> | |
| <h3 class="text-xl font-bold mb-2">Buy Tickets</h3> | |
| <p class="text-gray-300">Purchase tickets for $10 each. Each ticket gives you one entry into the monthly draw.</p> | |
| </div> | |
| <div class="text-center"> | |
| <div class="bg-yellow-500 text-black w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">2</div> | |
| <h3 class="text-xl font-bold mb-2">Wait for Draw</h3> | |
| <p class="text-gray-300">The draw happens automatically on the last day of each month at midnight UTC.</p> | |
| </div> | |
| <div class="text-center"> | |
| <div class="bg-yellow-500 text-black w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">3</div> | |
| <h3 class="text-xl font-bold mb-2">Win Big!</h3> | |
| <p class="text-gray-300">One lucky winner gets 80% of the total pot. We keep 20% as commission.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Previous Winners --> | |
| <section id="previous-winners" class="py-16 px-4 bg-black bg-opacity-30"> | |
| <div class="max-w-6xl mx-auto"> | |
| <h2 class="text-3xl font-bold mb-12 text-center">Previous Winners</h2> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <div class="bg-indigo-900 bg-opacity-50 p-6 rounded-xl relative overflow-hidden"> | |
| <div class="winner-badge absolute top-0 right-0 bg-yellow-500 text-black px-3 py-1 text-sm font-bold transform rotate-12 translate-x-2 -translate-y-2">WINNER</div> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-16 h-16 rounded-full bg-purple-600 flex items-center justify-center text-2xl font-bold mr-4">JD</div> | |
| <div> | |
| <h3 class="font-bold">John D.</h3> | |
| <p class="text-sm text-gray-300">May 2023</p> | |
| </div> | |
| </div> | |
| <div class="text-yellow-400 text-2xl font-bold mb-2">$3,840</div> | |
| <p class="text-sm">"I couldn't believe it when I won! The money was in my account within 24 hours."</p> | |
| </div> | |
| <div class="bg-indigo-900 bg-opacity-50 p-6 rounded-xl relative overflow-hidden"> | |
| <div class="winner-badge absolute top-0 right-0 bg-yellow-500 text-black px-3 py-1 text-sm font-bold transform rotate-12 translate-x-2 -translate-y-2">WINNER</div> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-16 h-16 rounded-full bg-pink-600 flex items-center justify-center text-2xl font-bold mr-4">SM</div> | |
| <div> | |
| <h3 class="font-bold">Sarah M.</h3> | |
| <p class="text-sm text-gray-300">April 2023</p> | |
| </div> | |
| </div> | |
| <div class="text-yellow-400 text-2xl font-bold mb-2">$2,960</div> | |
| <p class="text-sm">"This came at the perfect time. I used the money to pay off some medical bills."</p> | |
| </div> | |
| <div class="bg-indigo-900 bg-opacity-50 p-6 rounded-xl relative overflow-hidden"> | |
| <div class="winner-badge absolute top-0 right-0 bg-yellow-500 text-black px-3 py-1 text-sm font-bold transform rotate-12 translate-x-2 -translate-y-2">WINNER</div> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-16 h-16 rounded-full bg-blue-600 flex items-center justify-center text-2xl font-bold mr-4">RK</div> | |
| <div> | |
| <h3 class="font-bold">Robert K.</h3> | |
| <p class="text-sm text-gray-300">March 2023</p> | |
| </div> | |
| </div> | |
| <div class="text-yellow-400 text-2xl font-bold mb-2">$4,120</div> | |
| <p class="text-sm">"I bought just one ticket on a whim. Best $10 I ever spent!"</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Buy Tickets --> | |
| <section id="buy-tickets" class="py-16 px-4"> | |
| <div class="max-w-4xl mx-auto"> | |
| <h2 class="text-3xl font-bold mb-12 text-center">Buy Tickets</h2> | |
| <div class="bg-indigo-900 bg-opacity-50 rounded-xl p-6 mb-8"> | |
| <h3 class="text-xl font-bold mb-4">Select Number of Tickets</h3> | |
| <div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6"> | |
| <button class="ticket-option bg-indigo-700 hover:bg-indigo-600 py-4 rounded-lg transition" data-tickets="1"> | |
| <div class="text-2xl font-bold">1</div> | |
| <div class="text-sm">$10</div> | |
| </button> | |
| <button class="ticket-option bg-indigo-700 hover:bg-indigo-600 py-4 rounded-lg transition" data-tickets="5"> | |
| <div class="text-2xl font-bold">5</div> | |
| <div class="text-sm">$50</div> | |
| </button> | |
| <button class="ticket-option bg-indigo-700 hover:bg-indigo-600 py-4 rounded-lg transition" data-tickets="10"> | |
| <div class="text-2xl font-bold">10</div> | |
| <div class="text-sm">$100</div> | |
| </button> | |
| <button class="ticket-option bg-indigo-700 hover:bg-indigo-600 py-4 rounded-lg transition" data-tickets="20"> | |
| <div class="text-2xl font-bold">20</div> | |
| <div class="text-sm">$200</div> | |
| </button> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="custom-tickets" class="block mb-2">Or enter custom amount:</label> | |
| <input type="number" id="custom-tickets" min="1" max="100" class="w-full bg-indigo-800 border border-indigo-700 rounded-lg py-2 px-4 text-white" placeholder="Number of tickets"> | |
| </div> | |
| <div class="bg-black bg-opacity-30 p-4 rounded-lg mb-6"> | |
| <div class="flex justify-between mb-2"> | |
| <span>Tickets:</span> | |
| <span id="selected-tickets">0</span> | |
| </div> | |
| <div class="flex justify-between mb-2"> | |
| <span>Price per ticket:</span> | |
| <span>$10.00</span> | |
| </div> | |
| <div class="flex justify-between font-bold text-lg"> | |
| <span>Total:</span> | |
| <span id="total-price">$0.00</span> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="email" class="block mb-2">Email address (for ticket confirmation):</label> | |
| <input type="email" id="email" class="w-full bg-indigo-800 border border-indigo-700 rounded-lg py-2 px-4 text-white" placeholder="your@email.com"> | |
| </div> | |
| </div> | |
| <h3 class="text-xl font-bold mb-4 text-center">Choose Payment Method</h3> | |
| <div class="grid md:grid-cols-2 gap-6"> | |
| <!-- Stripe Payment --> | |
| <div class="bg-black bg-opacity-30 p-6 rounded-xl"> | |
| <div class="flex items-center mb-4"> | |
| <i class="fab fa-cc-stripe text-4xl text-purple-500 mr-3"></i> | |
| <h4 class="text-xl font-bold">Credit/Debit Card</h4> | |
| </div> | |
| <div id="stripe-payment" class="mb-4"> | |
| <div id="card-element" class="bg-white p-3 rounded-lg"></div> | |
| <div id="card-errors" role="alert" class="text-red-400 mt-2 text-sm"></div> | |
| </div> | |
| <button id="stripe-button" class="w-full bg-purple-600 hover:bg-purple-700 py-3 px-6 rounded-lg font-bold transition"> | |
| Pay with Card | |
| </button> | |
| </div> | |
| <!-- PayPal Payment --> | |
| <div class="bg-black bg-opacity-30 p-6 rounded-xl"> | |
| <div class="flex items-center mb-4"> | |
| <i class="fab fa-cc-paypal text-4xl text-blue-500 mr-3"></i> | |
| <h4 class="text-xl font-bold">PayPal</h4> | |
| </div> | |
| <div id="paypal-button-container" class="min-h-[50px]"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- FAQ --> | |
| <section class="py-16 px-4 bg-black bg-opacity-30"> | |
| <div class="max-w-4xl mx-auto"> | |
| <h2 class="text-3xl font-bold mb-12 text-center">Frequently Asked Questions</h2> | |
| <div class="space-y-4"> | |
| <div class="bg-indigo-900 bg-opacity-50 p-4 rounded-lg"> | |
| <button class="faq-question flex justify-between items-center w-full text-left font-bold"> | |
| <span>How is the winner selected?</span> | |
| <i class="fas fa-chevron-down transition-transform"></i> | |
| </button> | |
| <div class="faq-answer mt-2 hidden"> | |
| <p class="text-gray-300">The winner is selected randomly using a verified random number generator at the end of each month. The draw is conducted live on our YouTube channel for transparency.</p> | |
| </div> | |
| </div> | |
| <div class="bg-indigo-900 bg-opacity-50 p-4 rounded-lg"> | |
| <button class="faq-question flex justify-between items-center w-full text-left font-bold"> | |
| <span>How is the prize money distributed?</span> | |
| <i class="fas fa-chevron-down transition-transform"></i> | |
| </button> | |
| <div class="faq-answer mt-2 hidden"> | |
| <p class="text-gray-300">80% of the total ticket sales for the month goes to the winner, and 20% is kept by us as commission to cover operational costs and profit.</p> | |
| </div> | |
| </div> | |
| <div class="bg-indigo-900 bg-opacity-50 p-4 rounded-lg"> | |
| <button class="faq-question flex justify-between items-center w-full text-left font-bold"> | |
| <span>How will I receive my prize if I win?</span> | |
| <i class="fas fa-chevron-down transition-transform"></i> | |
| </button> | |
| <div class="faq-answer mt-2 hidden"> | |
| <p class="text-gray-300">We will contact you via the email you provided when purchasing tickets. You can choose to receive your prize via PayPal, bank transfer, or other agreed-upon methods.</p> | |
| </div> | |
| </div> | |
| <div class="bg-indigo-900 bg-opacity-50 p-4 rounded-lg"> | |
| <button class="faq-question flex justify-between items-center w-full text-left font-bold"> | |
| <span>Is this legal in my country?</span> | |
| <i class="fas fa-chevron-down transition-transform"></i> | |
| </button> | |
| <div class="faq-answer mt-2 hidden"> | |
| <p class="text-gray-300">Laws regarding online tombolas vary by jurisdiction. It is your responsibility to ensure participation is legal in your country/state. We cannot be held liable for any legal issues arising from your participation.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Footer --> | |
| <footer class="bg-black bg-opacity-80 py-8 px-4"> | |
| <div class="max-w-6xl mx-auto"> | |
| <div class="grid md:grid-cols-4 gap-8 mb-8"> | |
| <div> | |
| <h3 class="text-xl font-bold mb-4 flex items-center"> | |
| <i class="fas fa-trophy text-yellow-400 mr-2"></i> MonthlyTombola | |
| </h3> | |
| <p class="text-gray-400">Your chance to win big every month. 80% to the winner, 20% to us.</p> | |
| </div> | |
| <div> | |
| <h4 class="font-bold mb-4">Quick Links</h4> | |
| <ul class="space-y-2"> | |
| <li><a href="#how-it-works" class="text-gray-400 hover:text-white transition">How It Works</a></li> | |
| <li><a href="#current-draw" class="text-gray-400 hover:text-white transition">Current Draw</a></li> | |
| <li><a href="#previous-winners" class="text-gray-400 hover:text-white transition">Previous Winners</a></li> | |
| <li><a href="#buy-tickets" class="text-gray-400 hover:text-white transition">Buy Tickets</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-bold mb-4">Legal</h4> | |
| <ul class="space-y-2"> | |
| <li><a href="#" class="text-gray-400 hover:text-white transition">Terms of Service</a></li> | |
| <li><a href="#" class="text-gray-400 hover:text-white transition">Privacy Policy</a></li> | |
| <li><a href="#" class="text-gray-400 hover:text-white transition">Responsible Gaming</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-bold mb-4">Contact Us</h4> | |
| <ul class="space-y-2"> | |
| <li class="flex items-center text-gray-400"><i class="fas fa-envelope mr-2"></i> support@monthlytombola.com</li> | |
| <li class="flex items-center text-gray-400"><i class="fas fa-phone mr-2"></i> +1 (555) 123-4567</li> | |
| <li class="flex items-center text-gray-400"><i class="fab fa-twitter mr-2"></i> @MonthlyTombola</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="border-t border-gray-800 pt-6 text-center text-gray-500"> | |
| <p>© 2023 MonthlyTombola. All rights reserved.</p> | |
| <p class="text-xs mt-2">This is a fictional website created for demonstration purposes only.</p> | |
| </div> | |
| </div> | |
| </footer> | |
| <!-- Payment Success Modal --> | |
| <div id="payment-success-modal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-gradient-to-b from-purple-900 to-indigo-900 rounded-xl p-8 max-w-md w-full mx-4 relative"> | |
| <button id="close-modal" class="absolute top-4 right-4 text-2xl">×</button> | |
| <div class="text-center"> | |
| <div class="w-20 h-20 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-6"> | |
| <i class="fas fa-check text-3xl"></i> | |
| </div> | |
| <h3 class="text-2xl font-bold mb-4">Payment Successful!</h3> | |
| <p class="mb-6">Thank you for your purchase. Your tickets have been registered for the current monthly draw.</p> | |
| <div class="bg-black bg-opacity-30 p-4 rounded-lg mb-6"> | |
| <div class="flex justify-between mb-2"> | |
| <span>Tickets Purchased:</span> | |
| <span id="modal-tickets">5</span> | |
| </div> | |
| <div class="flex justify-between mb-2"> | |
| <span>Total Paid:</span> | |
| <span id="modal-total">$50.00</span> | |
| </div> | |
| <div class="flex justify-between font-bold text-yellow-400"> | |
| <span>Draw Date:</span> | |
| <span>June 30, 2023</span> | |
| </div> | |
| </div> | |
| <button id="modal-close-button" class="w-full bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg transition"> | |
| Close | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Mobile menu toggle | |
| document.getElementById('mobile-menu-button').addEventListener('click', function() { | |
| const menu = document.getElementById('mobile-menu'); | |
| menu.classList.toggle('hidden'); | |
| }); | |
| // FAQ accordion | |
| document.querySelectorAll('.faq-question').forEach(button => { | |
| button.addEventListener('click', () => { | |
| const answer = button.nextElementSibling; | |
| const icon = button.querySelector('i'); | |
| answer.classList.toggle('hidden'); | |
| icon.classList.toggle('rotate-180'); | |
| }); | |
| }); | |
| // Countdown timer | |
| function updateCountdown() { | |
| const now = new Date(); | |
| const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); | |
| endOfMonth.setHours(23, 59, 59, 999); | |
| const diff = endOfMonth - now; | |
| const days = Math.floor(diff / (1000 * 60 * 60 * 24)); | |
| const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); | |
| const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); | |
| const seconds = Math.floor((diff % (1000 * 60)) / 1000); | |
| document.getElementById('countdown').textContent = `${days}d ${hours}h ${minutes}m ${seconds}s`; | |
| document.getElementById('days-left').textContent = days; | |
| // Update draw date display | |
| const options = { year: 'numeric', month: 'long', day: 'numeric' }; | |
| document.getElementById('draw-date').textContent = endOfMonth.toLocaleDateString('en-US', options); | |
| } | |
| setInterval(updateCountdown, 1000); | |
| updateCountdown(); | |
| // Ticket selection | |
| let selectedTickets = 0; | |
| const ticketOptions = document.querySelectorAll('.ticket-option'); | |
| const customTicketsInput = document.getElementById('custom-tickets'); | |
| const selectedTicketsDisplay = document.getElementById('selected-tickets'); | |
| const totalPriceDisplay = document.getElementById('total-price'); | |
| const winnerPortionDisplay = document.getElementById('winner-portion'); | |
| function updateTicketSelection(tickets) { | |
| selectedTickets = tickets; | |
| selectedTicketsDisplay.textContent = tickets; | |
| const totalPrice = tickets * 10; | |
| totalPriceDisplay.textContent = `$${totalPrice.toFixed(2)}`; | |
| // Update current pot (simulated) | |
| const currentPot = 5420 + (tickets * 8); // 80% to pot | |
| document.getElementById('current-pot').textContent = currentPot.toLocaleString(); | |
| document.getElementById('tickets-sold').textContent = 542 + tickets; | |
| winnerPortionDisplay.textContent = Math.floor(currentPot * 0.8).toLocaleString(); | |
| // Update active state for buttons | |
| ticketOptions.forEach(option => { | |
| const optionTickets = parseInt(option.dataset.tickets); | |
| if (optionTickets === tickets) { | |
| option.classList.add('bg-yellow-500', 'text-black'); | |
| option.classList.remove('bg-indigo-700', 'hover:bg-indigo-600'); | |
| } else { | |
| option.classList.remove('bg-yellow-500', 'text-black'); | |
| option.classList.add('bg-indigo-700', 'hover:bg-indigo-600'); | |
| } | |
| }); | |
| } | |
| ticketOptions.forEach(option => { | |
| option.addEventListener('click', () => { | |
| const tickets = parseInt(option.dataset.tickets); | |
| updateTicketSelection(tickets); | |
| customTicketsInput.value = ''; | |
| }); | |
| }); | |
| customTicketsInput.addEventListener('input', () => { | |
| const tickets = parseInt(customTicketsInput.value) || 0; | |
| if (tickets > 0) { | |
| updateTicketSelection(tickets); | |
| // Remove active state from all buttons | |
| ticketOptions.forEach(option => { | |
| option.classList.remove('bg-yellow-500', 'text-black'); | |
| option.classList.add('bg-indigo-700', 'hover:bg-indigo-600'); | |
| }); | |
| } | |
| }); | |
| // Initialize with 0 tickets | |
| updateTicketSelection(0); | |
| // Stripe Payment | |
| const stripe = Stripe('pk_test_51N...'); // Replace with your test key | |
| const elements = stripe.elements(); | |
| const cardElement = elements.create('card', { | |
| style: { | |
| base: { | |
| color: '#32325d', | |
| fontFamily: '"Helvetica Neue", Helvetica, sans-serif', | |
| fontSmoothing: 'antialiased', | |
| fontSize: '16px', | |
| '::placeholder': { | |
| color: '#aab7c4' | |
| } | |
| }, | |
| invalid: { | |
| color: '#fa755a', | |
| iconColor: '#fa755a' | |
| } | |
| } | |
| }); | |
| cardElement.mount('#card-element'); | |
| const cardErrors = document.getElementById('card-errors'); | |
| cardElement.addEventListener('change', function(event) { | |
| if (event.error) { | |
| cardErrors.textContent = event.error.message; | |
| } else { | |
| cardErrors.textContent = ''; | |
| } | |
| }); | |
| document.getElementById('stripe-button').addEventListener('click', async function() { | |
| const email = document.getElementById('email').value; | |
| if (selectedTickets <= 0) { | |
| cardErrors.textContent = 'Please select at least one ticket'; | |
| return; | |
| } | |
| if (!email || !email.includes('@')) { | |
| cardErrors.textContent = 'Please enter a valid email address'; | |
| return; | |
| } | |
| const { error, paymentMethod } = await stripe.createPaymentMethod({ | |
| type: 'card', | |
| card: cardElement, | |
| billing_details: { | |
| email: email | |
| } | |
| }); | |
| if (error) { | |
| cardErrors.textContent = error.message; | |
| } else { | |
| // In a real app, you would send the paymentMethod.id to your server | |
| // Here we'll simulate a successful payment | |
| showPaymentSuccess(); | |
| } | |
| }); | |
| // PayPal Payment | |
| paypal.Buttons({ | |
| createOrder: function(data, actions) { | |
| const email = document.getElementById('email').value; | |
| if (selectedTickets <= 0) { | |
| alert('Please select at least one ticket'); | |
| return; | |
| } | |
| if (!email || !email.includes('@')) { | |
| alert('Please enter a valid email address'); | |
| return; | |
| } | |
| // In a real app, you would call your server to create the order | |
| // Here we'll simulate it | |
| const amount = (selectedTickets * 10).toFixed(2); | |
| return actions.order.create({ | |
| purchase_units: [{ | |
| amount: { | |
| value: amount | |
| } | |
| }] | |
| }); | |
| }, | |
| onApprove: function(data, actions) { | |
| // In a real app, you would capture the order on your server | |
| return actions.order.capture().then(function(details) { | |
| showPaymentSuccess(); | |
| }); | |
| }, | |
| onError: function(err) { | |
| console.error('PayPal error:', err); | |
| alert('There was an error processing your PayPal payment. Please try again.'); | |
| } | |
| }).render('#paypal-button-container'); | |
| // Payment success modal | |
| function showPaymentSuccess() { | |
| document.getElementById('modal-tickets').textContent = selectedTickets; | |
| document.getElementById('modal-total').textContent = `$${(selectedTickets * 10).toFixed(2)}`; | |
| document.getElementById('payment-success-modal').classList.remove('hidden'); | |
| } | |
| document.getElementById('close-modal').addEventListener('click', function() { | |
| document.getElementById('payment-success-modal').classList.add('hidden'); | |
| }); | |
| document.getElementById('modal-close-button').addEventListener('click', function() { | |
| document.getElementById('payment-success-modal').classList.add('hidden'); | |
| }); | |
| </script> | |
| </body> | |
| </html> |