Files
shopify-ai-backup/chat/public/select-plan.html

896 lines
43 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Select Your Plan | Plugin Compass</title>
<link rel="icon" type="image/png" href="/assets/Plugin.png">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif']
}
}
}
};
</script>
<style>
.glass-panel {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(0, 66, 37, 0.1);
}
.payment-modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(15, 23, 42, 0.7);
backdrop-filter: blur(8px);
z-index: 100000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.payment-modal-overlay.active {
opacity: 1;
visibility: visible;
}
.payment-modal {
background: #fff;
border-radius: 12px;
width: 95vw;
max-width: 1100px;
max-height: 96vh;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
transform: scale(0.95) translateY(8px);
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
display: flex;
flex-direction: column;
overflow: hidden;
height: auto;
}
.payment-modal-overlay.active .payment-modal {
transform: scale(1) translateY(0);
}
.payment-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 24px;
border-bottom: 1px solid #e2e8f0;
background: #fff;
flex-shrink: 0;
}
.payment-modal-header h3 {
margin: 0;
font-size: 18px;
font-weight: 700;
color: #1e293b;
}
.payment-modal-close {
background: none;
border: none;
font-size: 28px;
line-height: 1;
cursor: pointer;
color: #64748b;
padding: 0;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
transition: all 0.15s ease;
}
.payment-modal-close:hover {
background: rgba(0, 0, 0, 0.05);
color: #0f172a;
}
/* Make the frame container flexible and scrollable so iframe content fills the modal and isn't clipped */
.payment-frame-container {
display: flex;
flex: 1 1 auto;
overflow: auto; /* allow internal scrolling when needed */
min-height: 60vh;
background: #f8fafc;
height: auto;
}
.payment-frame-container iframe {
display: block;
width: 100%;
/* Fill the modal viewport while reserving space for the header (approx 72px)
using calc keeps the iframe from overflowing the modal and avoids clipping */
height: calc(96vh - 72px);
max-height: calc(96vh - 72px);
border: none;
}
</style>
<!-- PostHog Analytics -->
<script src="/posthog.js"></script>
</head>
<body class="bg-amber-50 text-gray-900 font-sans antialiased min-h-screen flex flex-col">
<!-- Navigation -->
<nav class="w-full z-50 transition-all duration-300">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-20">
<!-- Logo -->
<a href="/" class="flex-shrink-0 flex items-center gap-2 cursor-pointer">
<img src="/assets/Plugin.png" alt="Plugin Compass" class="w-8 h-8">
<span class="font-bold text-xl tracking-tight text-gray-800">Plugin<span
class="text-green-700">Compass</span></span>
</a>
<div class="text-sm text-gray-600">
Welcome to Plugin Compass
</div>
</div>
</div>
</nav>
<main class="flex-grow flex items-center justify-center px-4 py-12">
<div class="w-full max-w-5xl">
<div class="text-center mb-12">
<h1 class="text-4xl font-bold text-gray-900 mb-4">Choose your plan</h1>
<p class="text-xl text-gray-700">Start building your WordPress plugin today.</p>
<p class="text-sm text-gray-500 mt-2">You can always upgrade or downgrade later from your account
settings.</p>
</div>
<!-- Billing Cycle & Currency Selection -->
<div class="mb-8 flex flex-col sm:flex-row items-center justify-center gap-4">
<div class="inline-flex items-center bg-white p-1 rounded-full border border-gray-200">
<button id="monthly-toggle"
class="px-6 py-2 rounded-full text-sm font-medium bg-green-700 text-white shadow-sm transition-all">Monthly</button>
<button id="yearly-toggle"
class="px-6 py-2 rounded-full text-sm font-medium text-gray-600 hover:text-gray-900 transition-all">Yearly
<span class="text-green-600 font-bold">2 months free</span></button>
</div>
<div class="relative currency-dropdown" id="currency-dropdown">
<button id="currency-btn" class="bg-white border border-gray-200 rounded-full px-4 py-2 pr-10 text-sm font-medium text-gray-700 hover:border-green-700 hover:bg-gray-50 transition-all cursor-pointer flex items-center gap-2">
<span id="currency-flag">🇺🇸</span>
<span id="currency-code">USD</span>
</button>
<div id="currency-options" class="hidden absolute top-full left-0 mt-1 w-full bg-white border border-gray-200 rounded-xl shadow-lg z-50 overflow-hidden">
<button class="currency-option w-full px-4 py-2 text-sm text-gray-700 hover:bg-green-50 hover:text-gray-900 font-medium text-left flex items-center gap-2" data-value="USD">
🇺🇸 $<span class="ml-1">USD</span>
</button>
<button class="currency-option w-full px-4 py-2 text-sm text-gray-700 hover:bg-green-50 hover:text-gray-900 font-medium text-left flex items-center gap-2" data-value="GBP">
🇬🇧 £<span class="ml-1">GBP</span>
</button>
<button class="currency-option w-full px-4 py-2 text-sm text-gray-700 hover:bg-green-50 hover:text-gray-900 font-medium text-left flex items-center gap-2" data-value="EUR">
🇪🇺 €<span class="ml-1">EUR</span>
</button>
</div>
<i class="fa-solid fa-chevron-down absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 pointer-events-none text-xs transition-transform" id="currency-chevron"></i>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 w-full">
<!-- Hobby Plan -->
<div class="plan-card bg-white rounded-3xl p-8 border border-gray-100 shadow-xl shadow-gray-200/50 flex flex-col cursor-pointer transition-all hover:shadow-2xl hover:-translate-y-1"
data-plan="hobby">
<h3 class="text-xl font-bold text-gray-900 mb-2">Hobby</h3>
<p class="text-gray-600 text-sm mb-6">For personal projects and exploration.</p>
<div class="mb-6">
<span id="hobby-price" class="text-4xl font-bold text-gray-900">$0</span>
<span id="hobby-period" class="price-duration text-gray-500">/mo</span>
</div>
<ul class="space-y-4 mb-8 flex-grow">
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Up to 3 apps
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> No choice of ai models
</li>
<li class="flex items-center text-sm text-gray-700">
<a href="/credits" target="_blank" class="flex items-center text-green-700 hover:text-green-600 mr-1" title="Learn more about AI credits">
<i class="fa-solid fa-circle-question"></i>
</a>
<i class="fa-solid fa-check text-green-600 mr-3"></i> 50,000 monthly AI credits
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Standard queue
</li>
</ul>
<button type="button"
class="plan-btn w-full py-3 px-6 rounded-xl border-2 border-green-700 text-green-700 font-bold hover:bg-green-50 transition-colors text-center"
data-plan="hobby">
Start for Free
</button>
</div>
<!-- Starter Plan -->
<div class="plan-card bg-white rounded-3xl p-8 border border-gray-100 shadow-xl shadow-gray-200/50 flex flex-col cursor-pointer transition-all hover:shadow-2xl hover:-translate-y-1"
data-plan="starter">
<h3 class="text-xl font-bold text-gray-900 mb-2">Starter</h3>
<p class="text-gray-600 text-sm mb-6">Great for small business needs.</p>
<div class="mb-6">
<span id="starter-price" class="text-4xl font-bold text-gray-900">$7.50</span>
<span id="starter-period" class="price-duration text-gray-500">/mo</span>
</div>
<ul class="space-y-4 mb-8 flex-grow">
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Up to 10 apps
</li>
<li class="flex items-center text-sm text-gray-700">
<a href="/credits" target="_blank" class="flex items-center text-green-700 hover:text-green-600 mr-1" title="Learn more about AI credits">
<i class="fa-solid fa-circle-question"></i>
</a>
<i class="fa-solid fa-check text-green-600 mr-3"></i> 100,000 monthly AI credits
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Access to templates
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Faster queue than Hobby
</li>
</ul>
<button type="button"
class="plan-btn w-full py-3 px-6 rounded-xl border-2 border-green-700 text-green-700 font-bold hover:bg-green-50 transition-colors text-center"
data-plan="starter">
Choose Starter
</button>
</div>
<!-- Professional Plan -->
<div class="plan-card bg-white rounded-3xl p-8 border-2 border-green-700 shadow-2xl shadow-green-900/10 flex flex-col cursor-pointer transition-all hover:shadow-2xl hover:-translate-y-1 relative"
data-plan="professional">
<div
class="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-green-700 text-white text-xs font-bold px-4 py-1 rounded-full uppercase tracking-wider">
Most Popular
</div>
<h3 class="text-xl font-bold text-gray-900 mb-2">Professional</h3>
<p class="text-gray-600 text-sm mb-6">For serious WordPress plugin developers.</p>
<div class="mb-6">
<span id="pro-price" class="text-4xl font-bold text-gray-900">$25</span>
<span id="pro-period" class="price-duration text-gray-500">/mo</span>
</div>
<ul class="space-y-4 mb-8 flex-grow">
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Up to 20 apps
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Choice of AI models
</li>
<li class="flex items-center text-sm text-gray-700">
<a href="/credits" target="_blank" class="flex items-center text-green-700 hover:text-green-600 mr-1" title="Learn more about AI credits">
<i class="fa-solid fa-circle-question"></i>
</a>
<i class="fa-solid fa-check text-green-600 mr-3"></i> 5,000,000 Monthly AI credits
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Access to templates
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Priority queue (ahead of Hobby)
</li>
</ul>
<button type="button"
class="plan-btn w-full py-3 px-6 rounded-xl bg-green-700 text-white font-bold hover:bg-green-600 transition-all shadow-lg shadow-green-700/20 text-center"
data-plan="professional">
Get Started
</button>
</div>
<!-- Enterprise Plan -->
<div class="plan-card bg-white rounded-3xl p-8 border border-gray-100 shadow-xl shadow-gray-200/50 flex flex-col cursor-pointer transition-all hover:shadow-2xl hover:-translate-y-1"
data-plan="enterprise">
<h3 class="text-xl font-bold text-gray-900 mb-2">Enterprise</h3>
<p class="text-gray-600 text-sm mb-6">For teams and high-volume builders.</p>
<div class="mb-6">
<span id="enterprise-price" class="text-4xl font-bold text-gray-900">$75</span>
<span id="enterprise-period" class="price-duration text-gray-500">/mo</span>
</div>
<ul class="space-y-4 mb-8 flex-grow">
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Unlimited apps
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Fastest queue priority
</li>
<li class="flex items-center text-sm text-gray-700">
<a href="/credits" target="_blank" class="flex items-center text-green-700 hover:text-green-600 mr-1" title="Learn more about AI credits">
<i class="fa-solid fa-circle-question"></i>
</a>
<i class="fa-solid fa-check text-green-600 mr-3"></i> 50,000,000 monthly AI credits
</li>
<li class="flex items-center text-sm text-gray-700">
<i class="fa-solid fa-check text-green-600 mr-3"></i> Access to templates
</li>
</ul>
<button type="button"
class="plan-btn w-full py-3 px-6 rounded-xl border-2 border-green-700 text-green-700 font-bold hover:bg-green-50 transition-colors text-center"
data-plan="enterprise">
Choose Enterprise
</button>
</div>
</div>
<p class="text-center text-sm text-gray-600 mt-6">Queue priority: Enterprise first, then Professional, then
Hobby for faster responses.</p>
<p class="text-center text-sm text-gray-600 mt-2">
<a href="/credits" target="_blank" class="inline-flex items-center text-green-700 hover:text-green-600" title="Learn more about AI credits">
<i class="fa-solid fa-circle-question mr-1"></i>
</a>
Usage multipliers: Standard models burn 1x credits,
Advanced burn 2x, Premium burn 3x. Example: 2,500 tokens on a 2x model consume 5,000 credits.</p>
<p class="text-center text-sm text-gray-600 mt-2">Need more runway? Grab discounted AI energy boosts —
biggest breaks for Enterprise.</p>
</div>
</main>
<!-- Payment Modal -->
<div class="payment-modal-overlay" id="payment-modal">
<div class="payment-modal">
<div class="payment-modal-header">
<h3>Secure Checkout</h3>
<button type="button" class="payment-modal-close" id="payment-modal-close">&times;</button>
</div>
<div id="payment-frame-container" class="payment-frame-container"></div>
</div>
</div>
<footer class="bg-white border-t border-green-200 pt-16 pb-8">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 lg:grid-cols-5 gap-12 mb-16">
<div class="col-span-2 lg:col-span-1">
<div class="flex items-center gap-2 mb-6">
<img src="/assets/Plugin.png" alt="Plugin Compass" class="w-8 h-8">
<span class="font-bold text-xl tracking-tight text-gray-800">Plugin<span
class="text-green-700">Compass</span></span>
</div>
<p class="text-gray-600 text-sm leading-relaxed">
The smart way for WordPress site owners to replace expensive plugin subscriptions with custom
solutions. Save thousands monthly.
</p>
</div>
<div>
<h4 class="font-bold text-gray-900 mb-6">Product</h4>
<ul class="space-y-4 text-sm">
<li><a href="/features" class="text-gray-600 hover:text-green-700">Features</a></li>
<li><a href="/pricing" class="text-gray-600 hover:text-green-700">Pricing</a></li>
<li><a href="/templates.html" class="text-gray-600 hover:text-green-700">Templates</a></li>
</ul>
</div>
<div>
<h4 class="font-bold text-gray-900 mb-6">Resources</h4>
<ul class="space-y-4 text-sm">
<li><a href="/docs" class="text-gray-600 hover:text-green-700">Documentation</a></li>
<li><a href="/faq" class="text-gray-600 hover:text-green-700">FAQ</a></li>
</ul>
</div>
<div>
<h4 class="font-bold text-gray-900 mb-6">Legal</h4>
<ul class="space-y-4 text-sm">
<li><a href="/privacy.html" class="text-gray-600 hover:text-green-700">Privacy Policy</a></li>
<li><a href="/terms" class="text-gray-600 hover:text-green-700">Terms of Service</a></li>
<li><a href="/contact" class="text-gray-600 hover:text-green-700">Contact Us</a></li>
</ul>
</div>
<div class="col-span-2 lg:col-span-1">
<h4 class="font-bold text-gray-900 mb-6">Stay Updated</h4>
<p class="text-gray-600 text-sm mb-4">Get the latest updates and WordPress tips.</p>
<form id="footer-signup-form" class="flex flex-col gap-2">
<input type="email" name="email" placeholder="Your email" required
class="px-4 py-2 border border-green-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-700/20 text-sm">
<button type="submit"
class="bg-green-700 hover:bg-green-600 text-white px-4 py-2 rounded-lg font-medium text-sm transition-colors shadow-lg shadow-green-700/10">
Subscribe
</button>
</form>
<div id="signup-message" class="mt-2 text-xs hidden"></div>
</div>
</div>
<div class="border-t border-gray-100 pt-8 flex justify-center">
<p class="text-gray-500 text-xs text-center">© 2026 Plugin Compass. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Current selection state
let currentBillingCycle = 'monthly';
let currentCurrency = 'USD';
let isProcessing = false;
// Plan pricing configuration (matching pricing.html logic)
const planPricing = {
starter: {
monthly: { USD: 7.5, GBP: 5, EUR: 7.5 },
yearly: { USD: 75, GBP: 50, EUR: 75 }
},
professional: {
monthly: { USD: 25, GBP: 20, EUR: 25 },
yearly: { USD: 250, GBP: 200, EUR: 250 }
},
enterprise: {
monthly: { USD: 75, GBP: 60, EUR: 75 },
yearly: { USD: 750, GBP: 600, EUR: 750 }
}
};
// Currency symbols
const currencySymbols = {
USD: '$',
GBP: '£',
EUR: '€'
};
// Helper to get auth headers from localStorage
function getAuthHeaders() {
try {
const userStr = localStorage.getItem('wordpress_plugin_ai_user') || localStorage.getItem('shopify_ai_user');
if (userStr) {
const user = JSON.parse(userStr);
if (user && user.sessionToken) {
return { 'Authorization': `Bearer ${user.sessionToken}` };
}
}
} catch (err) {
console.warn('Failed to get auth headers from localStorage', err);
}
return {};
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
setupBillingCycleToggle();
setupCurrencyDropdown();
setupPlanSelection();
updatePlanPrices();
autoDetectCurrency();
// Check for pre-selected plan from URL query parameter
const urlParams = new URLSearchParams(window.location.search);
const preselectedPlan = urlParams.get('plan');
if (preselectedPlan) {
preselectPlan(preselectedPlan);
}
});
function preselectPlan(plan) {
const card = document.querySelector(`.plan-card[data-plan="${plan}"]`);
if (card) {
// Add visual selection state
const allCards = document.querySelectorAll('.plan-card');
allCards.forEach(c => {
c.classList.remove('ring-4', 'ring-green-700', 'ring-offset-2');
});
card.classList.add('ring-4', 'ring-green-700', 'ring-offset-2');
// Auto-trigger checkout for paid plans (hobby is free, no checkout needed)
if (plan !== 'hobby') {
// Small delay to ensure UI is ready
setTimeout(() => {
triggerPlanSelection(plan);
}, 100);
}
}
}
// Separate function to trigger plan selection (can be called from click or auto-trigger)
async function triggerPlanSelection(plan) {
// Don't process if already in progress
if (isProcessing) return;
const card = document.querySelector(`.plan-card[data-plan="${plan}"]`);
if (!card) return;
console.log('Plan selected:', plan);
isProcessing = true;
// Update UI state
const allCards = document.querySelectorAll('.plan-card');
allCards.forEach(c => {
c.classList.remove('ring-4', 'ring-green-700', 'ring-offset-2');
});
card.classList.add('ring-4', 'ring-green-700', 'ring-offset-2');
// Disable all buttons during selection
const allButtons = document.querySelectorAll('.plan-btn');
allButtons.forEach(btn => {
btn.disabled = true;
btn.textContent = 'Processing...';
btn.classList.add('opacity-50', 'cursor-not-allowed');
});
try {
const authHeaders = getAuthHeaders();
let data;
if (plan === 'hobby') {
// Hobby plan is free, use original endpoint
const response = await fetch('/api/select-plan', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...authHeaders
},
body: JSON.stringify({ plan }),
credentials: 'include',
});
data = await response.json();
if (response.ok && data.ok) {
window.location.href = '/apps';
} else {
throw new Error(data.error || 'Failed to select plan');
}
} else {
// Paid plans use inline subscription checkout
const response = await fetch('/api/subscription/checkout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...authHeaders
},
body: JSON.stringify({
plan: plan,
billingCycle: currentBillingCycle,
currency: currentCurrency.toLowerCase(),
inline: true,
previousPlan: (typeof window.currentPlan !== 'undefined' ? window.currentPlan : '')
}),
credentials: 'include',
});
data = await response.json();
if (response.ok && data.sessionId) {
// Use Dodo inline checkout - prefer inlineCheckoutUrl if available, otherwise use checkoutUrl
const checkoutUrl = data.inlineCheckoutUrl || data.checkoutUrl;
if (checkoutUrl) {
await openInlineCheckout(checkoutUrl, data.sessionId);
} else {
throw new Error('No checkout URL provided');
}
} else {
throw new Error(data.error || 'Failed to start checkout');
}
}
} catch (error) {
console.error('Error selecting plan:', error);
alert(error.message || 'Failed to select plan. Please try again.');
// Re-enable buttons
allButtons.forEach(btn => {
btn.disabled = false;
const planType = btn.getAttribute('data-plan');
if (planType === 'hobby') {
btn.textContent = 'Start for Free';
} else if (planType === 'starter') {
btn.textContent = 'Choose Starter';
} else if (planType === 'professional') {
btn.textContent = 'Get Started';
} else if (planType === 'enterprise') {
btn.textContent = 'Choose Enterprise';
}
btn.classList.remove('opacity-50', 'cursor-not-allowed');
});
isProcessing = false;
}
}
function setupBillingCycleToggle() {
const monthlyBtn = document.getElementById('monthly-toggle');
const yearlyBtn = document.getElementById('yearly-toggle');
if (!monthlyBtn || !yearlyBtn) return;
monthlyBtn.addEventListener('click', () => {
currentBillingCycle = 'monthly';
monthlyBtn.className = 'px-6 py-2 rounded-full text-sm font-medium bg-green-700 text-white shadow-sm transition-all';
yearlyBtn.className = 'px-6 py-2 rounded-full text-sm font-medium text-gray-600 hover:text-gray-900 transition-all';
updatePlanPrices();
});
yearlyBtn.addEventListener('click', () => {
currentBillingCycle = 'yearly';
yearlyBtn.className = 'px-6 py-2 rounded-full text-sm font-medium bg-green-700 text-white shadow-sm transition-all';
monthlyBtn.className = 'px-6 py-2 rounded-full text-sm font-medium text-gray-600 hover:text-gray-900 transition-all';
updatePlanPrices();
});
}
function setupCurrencyDropdown() {
const dropdown = document.getElementById('currency-dropdown');
const btn = document.getElementById('currency-btn');
const options = document.getElementById('currency-options');
const chevron = document.getElementById('currency-chevron');
if (!dropdown || !btn || !options) return;
btn.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = !dropdown.classList.contains('open');
if (isOpen) {
dropdown.classList.add('open');
options.classList.remove('hidden');
if (chevron) chevron.style.transform = 'rotate(180deg)';
} else {
dropdown.classList.remove('open');
options.classList.add('hidden');
if (chevron) chevron.style.transform = 'rotate(0deg)';
}
});
// Handle currency selection
document.querySelectorAll('.currency-option').forEach(option => {
option.addEventListener('click', (e) => {
e.preventDefault();
const currency = option.getAttribute('data-value');
currentCurrency = currency;
// Update button display
const flags = { USD: '🇺🇸', GBP: '🇬🇧', EUR: '🇪🇺' };
const flagEl = document.getElementById('currency-flag');
const codeEl = document.getElementById('currency-code');
if (flagEl) flagEl.textContent = flags[currency];
if (codeEl) codeEl.textContent = currency;
// Close dropdown
dropdown.classList.remove('open');
options.classList.add('hidden');
if (chevron) chevron.style.transform = 'rotate(0deg)';
updatePlanPrices();
});
});
// Close dropdown when clicking outside
document.addEventListener('click', () => {
dropdown.classList.remove('open');
options.classList.add('hidden');
if (chevron) chevron.style.transform = 'rotate(0deg)';
});
}
function updatePlanPrices() {
// Update Hobby plan price
const hobbyPrice = document.getElementById('hobby-price');
const hobbyPeriod = document.getElementById('hobby-period');
if (hobbyPrice) hobbyPrice.textContent = currencySymbols[currentCurrency] + '0';
if (hobbyPeriod) hobbyPeriod.textContent = currentBillingCycle === 'monthly' ? '/mo' : '/yr';
// Update Starter plan price
const starterPrice = document.getElementById('starter-price');
const starterPeriod = document.getElementById('starter-period');
const starterAmount = planPricing.starter[currentBillingCycle][currentCurrency];
if (starterPrice) starterPrice.textContent = currencySymbols[currentCurrency] + starterAmount.toFixed(starterAmount % 1 === 0 ? 0 : 2);
if (starterPeriod) starterPeriod.textContent = currentBillingCycle === 'monthly' ? '/mo' : '/yr';
// Update Professional plan price
const proPrice = document.getElementById('pro-price');
const proPeriod = document.getElementById('pro-period');
const proAmount = planPricing.professional[currentBillingCycle][currentCurrency];
if (proPrice) proPrice.textContent = currencySymbols[currentCurrency] + proAmount.toFixed(proAmount % 1 === 0 ? 0 : 2);
if (proPeriod) proPeriod.textContent = currentBillingCycle === 'monthly' ? '/mo' : '/yr';
// Update Enterprise plan price
const enterprisePrice = document.getElementById('enterprise-price');
const enterprisePeriod = document.getElementById('enterprise-period');
const enterpriseAmount = planPricing.enterprise[currentBillingCycle][currentCurrency];
if (enterprisePrice) enterprisePrice.textContent = currencySymbols[currentCurrency] + enterpriseAmount.toFixed(enterpriseAmount % 1 === 0 ? 0 : 2);
if (enterprisePeriod) enterprisePeriod.textContent = currentBillingCycle === 'monthly' ? '/mo' : '/yr';
}
function setupPlanSelection() {
// Only handle card clicks to avoid double-triggering
document.querySelectorAll('.plan-card').forEach(card => {
card.addEventListener('click', async (e) => {
// Let links within the card work normally
if (e.target.closest('a')) return;
e.preventDefault();
const plan = card.getAttribute('data-plan');
if (!plan) return;
// Use the shared triggerPlanSelection function
triggerPlanSelection(plan);
});
});
// Prevent button clicks from bubbling to card (card listener handles everything)
document.querySelectorAll('.plan-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
// Just let it bubble to the card
});
});
}
// Detect Location and Set Currency
async function autoDetectCurrency() {
try {
const response = await fetch('https://ipapi.co/json/');
const data = await response.json();
if (data.currency && currencySymbols[data.currency]) {
currentCurrency = data.currency;
// Update button display
const flags = { USD: '🇺🇸', GBP: '🇬🇧', EUR: '🇪🇺' };
const flagEl = document.getElementById('currency-flag');
const codeEl = document.getElementById('currency-code');
if (flagEl) flagEl.textContent = flags[currentCurrency];
if (codeEl) codeEl.textContent = currentCurrency;
updatePlanPrices();
}
} catch (err) {
console.log('Currency detection failed, defaulting to USD');
}
}
async function openInlineCheckout(checkoutUrl, sessionId) {
const modal = document.getElementById('payment-modal');
const container = document.getElementById('payment-frame-container');
container.innerHTML = `<iframe src="${checkoutUrl}" allowpaymentrequest="true"></iframe>`;
modal.classList.add('active');
let pollCount = 0;
const maxPolls = 180;
const pollInterval = 1000;
const checkPaymentStatus = async () => {
try {
pollCount++;
const resp = await fetch(`/api/subscription/confirm?session_id=${encodeURIComponent(sessionId)}`, {
credentials: 'include'
});
if (resp.ok) {
const data = await resp.json();
if (data.ok) {
clearInterval(pollTimer);
closeCheckoutModal();
window.location.href = '/apps';
return;
}
}
if (pollCount >= maxPolls) {
clearInterval(pollTimer);
closeCheckoutModal();
alert('Payment confirmation timeout. Please check your account status.');
reenableButtons();
isProcessing = false;
}
} catch (error) {
console.error('Error checking payment status:', error);
}
};
const pollTimer = setInterval(checkPaymentStatus, pollInterval);
function closeCheckoutModal() {
clearInterval(pollTimer);
modal.classList.remove('active');
container.innerHTML = '';
}
function reenableButtons() {
const allButtons = document.querySelectorAll('.plan-btn');
allButtons.forEach(btn => {
btn.disabled = false;
const planType = btn.getAttribute('data-plan');
if (planType === 'hobby') {
btn.textContent = 'Start for Free';
} else if (planType === 'starter') {
btn.textContent = 'Choose Starter';
} else if (planType === 'professional') {
btn.textContent = 'Get Started';
} else if (planType === 'enterprise') {
btn.textContent = 'Choose Enterprise';
}
btn.classList.remove('opacity-50', 'cursor-not-allowed');
});
}
document.getElementById('payment-modal-close').onclick = () => {
closeCheckoutModal();
reenableButtons();
isProcessing = false;
};
modal.onclick = (e) => {
if (e.target === modal) {
closeCheckoutModal();
reenableButtons();
isProcessing = false;
}
};
const handleEsc = (e) => {
if (e.key === 'Escape') {
closeCheckoutModal();
reenableButtons();
isProcessing = false;
}
};
document.addEventListener('keydown', handleEsc);
}
// Email Signup Form Handler
const signupForm = document.getElementById('footer-signup-form');
const signupMessage = document.getElementById('signup-message');
if (signupForm) {
signupForm.addEventListener('submit', async (e) => {
e.preventDefault();
const email = signupForm.querySelector('input[name="email"]').value;
const button = signupForm.querySelector('button');
button.disabled = true;
button.textContent = 'Subscribing...';
try {
const response = await fetch('https://emailmarketing.modelrailway3d.co.uk/api/webhooks/incoming/wh_0Z49zi_DGj4-lKJMOPO8-g', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
source: 'plugin_compass_select_plan',
timestamp: new Date().toISOString()
})
});
if (response.ok) {
signupMessage.textContent = 'Successfully subscribed!';
signupMessage.className = 'mt-2 text-xs text-green-600';
signupForm.reset();
} else {
throw new Error('Failed to subscribe');
}
} catch (error) {
signupMessage.textContent = 'Failed to subscribe. Please try again.';
signupMessage.className = 'mt-2 text-xs text-red-600';
} finally {
signupMessage.classList.remove('hidden');
button.disabled = false;
button.textContent = 'Subscribe';
setTimeout(() => {
signupMessage.classList.add('hidden');
}, 5000);
}
});
}
</script>
</body>
</html>