(async () => { const cfg = await fetch("/config").then(r => r.json()); const stripe = Stripe(cfg.publishableKey); const subscriptionForm = document.getElementById("subscription-form"); const subscriptionResult = document.getElementById("subscription-result"); const tierSelect = document.getElementById("subscription-tier"); const emailInput = document.getElementById("subscriber-email"); const nameInput = document.getElementById("subscriber-name"); const submitButton = document.getElementById("subscription-submit-button"); let subscriptionElements, subscriptionCardElement; // Initialize tier button selection function initializeTierButtons() { const tierButtons = document.querySelectorAll('.tier-button'); const tierInput = document.getElementById('subscription-tier'); tierButtons.forEach(button => { button.addEventListener('click', function() { // Remove selected class from all buttons tierButtons.forEach(btn => btn.classList.remove('selected')); // Add selected class to clicked button this.classList.add('selected'); // Update the tier input value const selectedTier = this.getAttribute('data-tier'); if (tierInput) { tierInput.value = selectedTier; } }); }); } // Initialize basic card element (display only, no payment processing) function initializeBasicCardElement() { // Clean up existing elements if (subscriptionElements) { subscriptionElements.destroy(); } // Create basic elements for card display subscriptionElements = stripe.elements({ appearance: { theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'night' : 'stripe' } }); // Create and mount card element subscriptionCardElement = subscriptionElements.create("card", { style: { base: { fontSize: '16px', color: getComputedStyle(document.documentElement).getPropertyValue('--text-primary'), '::placeholder': { color: getComputedStyle(document.documentElement).getPropertyValue('--text-secondary'), }, }, } }); subscriptionCardElement.mount("#subscription-card-element"); } // Handle subscription payment async function handleSubscriptionPayment(e) { e.preventDefault(); const tier_id = tierSelect.value; const email = emailInput.value; const name = nameInput.value; if (!tier_id || !email) { subscriptionResult.textContent = "❌ Please fill in all required fields."; return; } subscriptionResult.textContent = "Creating subscription..."; submitButton.disabled = true; try { // Create subscription const res = await fetch("/create-subscription", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tier_id, email, name }) }); const data = await res.json(); if (data.error) { subscriptionResult.textContent = "❌ " + data.error; submitButton.disabled = false; return; } const clientSecret = data.clientSecret; subscriptionResult.textContent = "Processing payment..."; // Confirm payment with the card element const { error } = await stripe.confirmPayment({ elements: subscriptionElements, confirmParams: { return_url: window.location.href, }, redirect: "if_required" }); if (error) { subscriptionResult.textContent = "❌ " + error.message; } else { subscriptionResult.innerHTML = "✅ Thank you! Your subscription is now active.
You'll receive an email confirmation shortly."; showSubscriptionSuccessAnimation(); // Add to supporter wall const name = nameInput.value.trim(); if (name && window.supporterWall) { const tierData = await getTierData(tier_id); await window.supporterWall.addSupporter(name, tierData.amount * 100, tierData.currency); } } } catch (err) { subscriptionResult.textContent = "❌ Subscription failed. Please try again."; console.error(err); } finally { submitButton.disabled = false; } } // Get tier data async function getTierData(tierId) { const tiers = await fetch("/subscription-tiers").then(r => r.json()); return tiers.tiers[tierId]; } // Success animation for subscriptions function showSubscriptionSuccessAnimation() { subscriptionResult.style.background = 'linear-gradient(135deg, #28a745, #20c997)'; subscriptionResult.style.color = 'white'; subscriptionResult.style.padding = '12px'; subscriptionResult.style.borderRadius = '8px'; subscriptionResult.style.animation = 'bounce 0.6s ease-out'; } // Update submit button text based on tier async function updateSubmitButtonText() { const tier_id = tierSelect.value; if (tier_id) { try { const tierData = await getTierData(tier_id); if (tierData.interval === 'month') { submitButton.textContent = `Start Monthly Support - ${tierData.currency} ${tierData.amount}/${tierData.interval}`; } else { submitButton.textContent = `Start Yearly Support - ${tierData.currency} ${tierData.amount}/${tierData.interval}`; } } catch (err) { submitButton.textContent = "Start Support"; } } else { submitButton.textContent = "Start Support"; } } // Event listeners subscriptionForm.addEventListener("submit", handleSubscriptionPayment); tierSelect.addEventListener("change", updateSubmitButtonText); // Tab switching functionality const oneTimeTab = document.getElementById("one-time-tab"); const recurringTab = document.getElementById("recurring-tab"); const donationForm = document.getElementById("donation-form"); function switchToOneTime() { oneTimeTab.classList.add("active"); recurringTab.classList.remove("active"); donationForm.classList.add("active"); subscriptionForm.classList.remove("active"); } function switchToRecurring() { recurringTab.classList.add("active"); oneTimeTab.classList.remove("active"); subscriptionForm.classList.add("active"); donationForm.classList.remove("active"); // Initialize card element when switching to subscription tab if (!subscriptionElements) { initializeBasicCardElement(); } } oneTimeTab.addEventListener("click", switchToOneTime); recurringTab.addEventListener("click", switchToRecurring); // Update elements theme when theme changes if (window.themeManager) { const originalSetTheme = window.themeManager.setTheme; window.themeManager.setTheme = function(theme) { originalSetTheme.call(this, theme); // Reinitialize card element with new theme setTimeout(() => { if (subscriptionForm.classList.contains("active")) { initializeBasicCardElement(); } }, 100); }; } // Initialize card element on page load if subscription form is visible if (subscriptionForm.classList.contains("active")) { initializeBasicCardElement(); } // Initialize tier button selection initializeTierButtons(); })();