Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
375
chat/public/subscription-success.html
Normal file
375
chat/public/subscription-success.html
Normal file
@@ -0,0 +1,375 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Subscription Activated | 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);
|
||||
}
|
||||
</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-2xl">
|
||||
<!-- Success Message -->
|
||||
<div class="text-center mb-8">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 bg-green-100 rounded-full mb-4">
|
||||
<i class="fas fa-check text-green-600 text-2xl"></i>
|
||||
</div>
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-4">Subscription Activated!</h1>
|
||||
<p class="text-lg text-gray-700 mb-6">Your subscription has been successfully activated and you're ready to start building.</p>
|
||||
</div>
|
||||
|
||||
<!-- Subscription Details -->
|
||||
<div class="bg-white rounded-2xl p-8 shadow-xl border border-gray-100 mb-8" id="subscription-details">
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center px-4 py-2 bg-green-100 text-green-800 rounded-full text-sm font-medium mb-4">
|
||||
<i class="fas fa-credit-card mr-2"></i>
|
||||
<span id="plan-display">Starter Plan</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-6">
|
||||
<div class="text-center">
|
||||
<div class="text-sm text-gray-500 mb-1">Billing Cycle</div>
|
||||
<div class="font-semibold text-gray-900" id="billing-cycle">Monthly</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-sm text-gray-500 mb-1">Currency</div>
|
||||
<div class="font-semibold text-gray-900" id="currency-display">USD</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-sm text-gray-500 mb-1">Next Billing</div>
|
||||
<div class="font-semibold text-gray-900" id="next-billing">Loading...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="text-center space-y-4">
|
||||
<a href="/apps"
|
||||
class="inline-flex items-center px-8 py-3 bg-green-700 text-white font-bold rounded-xl hover:bg-green-600 transition-all shadow-lg shadow-green-700/20 hover:shadow-green-700/40 transform hover:-translate-y-0.5">
|
||||
<i class="fas fa-rocket mr-2"></i>
|
||||
Start Building Apps
|
||||
</a>
|
||||
|
||||
<div class="text-sm text-gray-600">
|
||||
<a href="/settings" class="text-green-700 hover:text-green-600 font-medium">
|
||||
Manage your subscription
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Getting Started Tips -->
|
||||
<div class="mt-12 bg-green-50 rounded-2xl p-6 border border-green-200">
|
||||
<h3 class="font-semibold text-gray-900 mb-3 flex items-center">
|
||||
<i class="fas fa-lightbulb text-green-600 mr-2"></i>
|
||||
What's Next?
|
||||
</h3>
|
||||
<ul class="space-y-2 text-sm text-gray-700">
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-check text-green-600 mr-2 mt-0.5"></i>
|
||||
<span>Create your first WordPress plugin using our AI builder</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-check text-green-600 mr-2 mt-0.5"></i>
|
||||
<span>Access premium templates and advanced features</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-check text-green-600 mr-2 mt-0.5"></i>
|
||||
<span>Export and deploy your plugins anytime</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="py-8 text-center text-gray-500 text-xs">
|
||||
<p>© 2026 Plugin Compass. All rights reserved.</p>
|
||||
<div style="margin-top: 12px; display: flex; justify-content: center; gap: 16px;">
|
||||
<a href="/terms" style="color: #008060; text-decoration: none;">Terms</a>
|
||||
<a href="/privacy" style="color: #008060; text-decoration: none;">Privacy</a>
|
||||
<a href="/contact" style="color: #008060; text-decoration: none;">Contact Us</a>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<script>
|
||||
// Get session ID from URL parameters
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const sessionId = urlParams.get('session_id') || urlParams.get('checkout_id') || urlParams.get('session');
|
||||
|
||||
async function confirmSubscription() {
|
||||
if (!sessionId) {
|
||||
// No session id present - attempt to verify status in the background then redirect to /apps
|
||||
showPending('Checking subscription status. This may take a few seconds...');
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 8;
|
||||
const intervalMs = 2000;
|
||||
|
||||
async function checkStatusOnce() {
|
||||
attempts++;
|
||||
try {
|
||||
const resp = await fetch('/api/subscription/status', {
|
||||
method: 'GET',
|
||||
credentials: 'include'
|
||||
});
|
||||
if (resp.ok) {
|
||||
const statusData = await resp.json();
|
||||
if (statusData.hasActiveSubscription) {
|
||||
// Subscription is active - go to apps page
|
||||
window.location.href = '/apps';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Subscription status check failed', err);
|
||||
}
|
||||
|
||||
if (attempts >= maxAttempts) {
|
||||
showError('Unable to confirm subscription automatically. Visit Settings to check or go to Apps.');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const intervalId = setInterval(async () => {
|
||||
const done = await checkStatusOnce();
|
||||
if (done) clearInterval(intervalId);
|
||||
}, intervalMs);
|
||||
|
||||
// Run an immediate check
|
||||
await checkStatusOnce();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const authHeaders = getAuthHeaders();
|
||||
const response = await fetch(`/api/subscription/confirm?session_id=${encodeURIComponent(sessionId)}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
...authHeaders
|
||||
},
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok && data.ok) {
|
||||
updateLocalStorageUser(data);
|
||||
updateSubscriptionDisplay(data);
|
||||
} else if (data.pending) {
|
||||
showPending('Payment is still processing. Please wait...');
|
||||
} else {
|
||||
showError(data.error || 'Failed to activate subscription');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error confirming subscription:', error);
|
||||
showError('Network error. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {};
|
||||
}
|
||||
|
||||
function updateSubscriptionDisplay(data) {
|
||||
// Update plan display
|
||||
const planDisplay = document.getElementById('plan-display');
|
||||
if (planDisplay) {
|
||||
planDisplay.textContent = getPlanDisplayName(data.plan);
|
||||
}
|
||||
|
||||
// Update billing cycle
|
||||
const billingCycle = document.getElementById('billing-cycle');
|
||||
if (billingCycle) {
|
||||
billingCycle.textContent = data.billingCycle ?
|
||||
data.billingCycle.charAt(0).toUpperCase() + data.billingCycle.slice(1) : 'Monthly';
|
||||
}
|
||||
|
||||
// Update currency
|
||||
const currencyDisplay = document.getElementById('currency-display');
|
||||
if (currencyDisplay) {
|
||||
currencyDisplay.textContent = data.currency ?
|
||||
data.currency.toUpperCase() : 'USD';
|
||||
}
|
||||
|
||||
// Calculate next billing date
|
||||
const nextBilling = document.getElementById('next-billing');
|
||||
if (nextBilling && data.billingCycle) {
|
||||
const nextDate = calculateNextBillingDate(data.billingCycle);
|
||||
nextBilling.textContent = nextDate.toLocaleDateString();
|
||||
}
|
||||
|
||||
// Display payment method if available
|
||||
const paymentMethod = data.account?.paymentMethod;
|
||||
if (paymentMethod && paymentMethod.last4) {
|
||||
const planBadge = document.getElementById('plan-display')?.parentElement;
|
||||
if (planBadge) {
|
||||
const brand = paymentMethod.brand || 'Card';
|
||||
const last4 = paymentMethod.last4;
|
||||
planBadge.innerHTML = `
|
||||
<i class="fas fa-credit-card mr-2"></i>
|
||||
<span id="plan-display">${getPlanDisplayName(data.plan)}</span>
|
||||
<span class="ml-3 text-gray-500 text-sm">(${brand} ••••• ${last4})</span>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// Track successful subscription
|
||||
if (window.posthog) {
|
||||
window.posthog.capture('subscription_activated', {
|
||||
plan: data.plan,
|
||||
billing_cycle: data.billingCycle,
|
||||
currency: data.currency
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateLocalStorageUser(data) {
|
||||
try {
|
||||
const userStr = localStorage.getItem('wordpress_plugin_ai_user') || localStorage.getItem('shopify_ai_user');
|
||||
if (userStr) {
|
||||
const user = JSON.parse(userStr);
|
||||
if (user && data.account) {
|
||||
user.plan = data.account.plan;
|
||||
user.billingStatus = data.account.billingStatus;
|
||||
user.billingCycle = data.account.billingCycle;
|
||||
user.subscriptionRenewsAt = data.account.subscriptionRenewsAt;
|
||||
user.billingEmail = data.account.billingEmail;
|
||||
localStorage.setItem('wordpress_plugin_ai_user', JSON.stringify(user));
|
||||
localStorage.setItem('shopify_ai_user', JSON.stringify(user));
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Failed to update localStorage user', err);
|
||||
}
|
||||
}
|
||||
|
||||
function showPending(message) {
|
||||
const subscriptionDetails = document.getElementById('subscription-details');
|
||||
if (subscriptionDetails) {
|
||||
subscriptionDetails.innerHTML = `
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 bg-yellow-100 rounded-full mb-4">
|
||||
<i class="fas fa-clock text-yellow-600 text-2xl"></i>
|
||||
</div>
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">Processing Payment</h2>
|
||||
<p class="text-gray-600 mb-4">${message}</p>
|
||||
<button onclick="location.reload()" class="px-6 py-2 bg-green-700 text-white rounded-lg hover:bg-green-600 transition-colors">
|
||||
Refresh Status
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
const subscriptionDetails = document.getElementById('subscription-details');
|
||||
if (subscriptionDetails) {
|
||||
subscriptionDetails.innerHTML = `
|
||||
<div class="text-center">
|
||||
<div class="inline-flex items-center justify-center w-16 h-16 bg-red-100 rounded-full mb-4">
|
||||
<i class="fas fa-exclamation-triangle text-red-600 text-2xl"></i>
|
||||
</div>
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">Subscription Error</h2>
|
||||
<p class="text-gray-600 mb-4">${message}</p>
|
||||
<div class="space-y-2">
|
||||
<a href="/select-plan" class="block px-6 py-2 bg-green-700 text-white rounded-lg hover:bg-green-600 transition-colors">
|
||||
Try Again
|
||||
</a>
|
||||
<a href="/contact" class="block px-6 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors">
|
||||
Contact Support
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function getPlanDisplayName(plan) {
|
||||
const planNames = {
|
||||
'hobby': 'Hobby Plan',
|
||||
'starter': 'Starter Plan',
|
||||
'professional': 'Professional Plan',
|
||||
'business': 'Professional Plan',
|
||||
'enterprise': 'Enterprise Plan'
|
||||
};
|
||||
return planNames[plan] || `${plan.charAt(0).toUpperCase() + plan.slice(1)} Plan`;
|
||||
}
|
||||
|
||||
function calculateNextBillingDate(billingCycle) {
|
||||
const now = new Date();
|
||||
if (billingCycle === 'yearly') {
|
||||
return new Date(now.getFullYear() + 1, now.getMonth(), now.getDate());
|
||||
} else {
|
||||
return new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
confirmSubscription();
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user