Plugin Directory

Changeset 3395869


Ignore:
Timestamp:
11/14/2025 04:48:32 PM (3 months ago)
Author:
2wstechnologies
Message:

fix the subscriptions upgrade logic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • askeet/trunk/askeet.php

    r3395647 r3395869  
    12421242    </div>
    12431243
     1244    <!-- Modern Modal for subscription actions -->
     1245    <div id="askeet-modal-overlay" class="askeet-modal-overlay">
     1246        <div class="askeet-modal">
     1247            <div class="askeet-modal-icon" id="askeet-modal-icon">
     1248                <!-- Icon will be injected here -->
     1249            </div>
     1250            <h2 class="askeet-modal-title" id="askeet-modal-title">Title</h2>
     1251            <p class="askeet-modal-message" id="askeet-modal-message">Message</p>
     1252            <div class="askeet-modal-actions" id="askeet-modal-actions">
     1253                <button class="askeet-modal-btn askeet-modal-btn-primary" id="askeet-modal-btn-primary">OK</button>
     1254            </div>
     1255        </div>
     1256    </div>
     1257
     1258    <style>
     1259    /* Modern Modal Styles */
     1260    .askeet-modal-overlay {
     1261        display: none;
     1262        position: fixed;
     1263        top: 0;
     1264        left: 0;
     1265        width: 100%;
     1266        height: 100%;
     1267        background: rgba(0, 0, 0, 0.6);
     1268        backdrop-filter: blur(8px);
     1269        z-index: 999999;
     1270        opacity: 0;
     1271        transition: opacity 0.3s ease;
     1272    }
     1273
     1274    .askeet-modal-overlay.active {
     1275        display: flex;
     1276        align-items: center;
     1277        justify-content: center;
     1278        opacity: 1;
     1279    }
     1280
     1281    .askeet-modal {
     1282        background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
     1283        border-radius: 20px;
     1284        padding: 40px 30px;
     1285        max-width: 480px;
     1286        width: 90%;
     1287        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
     1288        transform: scale(0.7);
     1289        opacity: 0;
     1290        transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
     1291        text-align: center;
     1292        position: relative;
     1293        overflow: hidden;
     1294    }
     1295
     1296    .askeet-modal::before {
     1297        content: '';
     1298        position: absolute;
     1299        top: 0;
     1300        left: 0;
     1301        width: 100%;
     1302        height: 4px;
     1303        background: linear-gradient(90deg, #005a9e 0%, #0088cc 100%);
     1304    }
     1305
     1306    .askeet-modal-overlay.active .askeet-modal {
     1307        transform: scale(1);
     1308        opacity: 1;
     1309    }
     1310
     1311    .askeet-modal-icon {
     1312        width: 80px;
     1313        height: 80px;
     1314        margin: 0 auto 20px;
     1315        border-radius: 50%;
     1316        display: flex;
     1317        align-items: center;
     1318        justify-content: center;
     1319        font-size: 40px;
     1320        animation: iconPop 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.2s both;
     1321    }
     1322
     1323    @keyframes iconPop {
     1324        0% {
     1325            transform: scale(0);
     1326            opacity: 0;
     1327        }
     1328        50% {
     1329            transform: scale(1.2);
     1330        }
     1331        100% {
     1332            transform: scale(1);
     1333            opacity: 1;
     1334        }
     1335    }
     1336
     1337    .askeet-modal-icon.success {
     1338        background: linear-gradient(135deg, #4caf50 0%, #45a049 100%);
     1339        box-shadow: 0 8px 24px rgba(76, 175, 80, 0.3);
     1340    }
     1341
     1342    .askeet-modal-icon.error {
     1343        background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
     1344        box-shadow: 0 8px 24px rgba(244, 67, 54, 0.3);
     1345    }
     1346
     1347    .askeet-modal-icon.loading {
     1348        background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%);
     1349        box-shadow: 0 8px 24px rgba(33, 150, 243, 0.3);
     1350    }
     1351
     1352    .askeet-modal-icon.loading::after {
     1353        content: '';
     1354        width: 30px;
     1355        height: 30px;
     1356        border: 3px solid #ffffff;
     1357        border-top-color: transparent;
     1358        border-radius: 50%;
     1359        animation: spin 0.8s linear infinite;
     1360    }
     1361
     1362    @keyframes spin {
     1363        to { transform: rotate(360deg); }
     1364    }
     1365
     1366    .askeet-modal-title {
     1367        font-size: 24px;
     1368        font-weight: 700;
     1369        color: #1a1a1a;
     1370        margin: 0 0 12px 0;
     1371        animation: slideDown 0.4s ease 0.3s both;
     1372    }
     1373
     1374    .askeet-modal-message {
     1375        font-size: 16px;
     1376        color: #666;
     1377        line-height: 1.6;
     1378        margin: 0 0 30px 0;
     1379        animation: slideDown 0.4s ease 0.4s both;
     1380    }
     1381
     1382    @keyframes slideDown {
     1383        from {
     1384            opacity: 0;
     1385            transform: translateY(-10px);
     1386        }
     1387        to {
     1388            opacity: 1;
     1389            transform: translateY(0);
     1390        }
     1391    }
     1392
     1393    .askeet-modal-actions {
     1394        display: flex;
     1395        gap: 12px;
     1396        justify-content: center;
     1397        animation: slideDown 0.4s ease 0.5s both;
     1398    }
     1399
     1400    .askeet-modal-btn {
     1401        padding: 14px 32px;
     1402        border: none;
     1403        border-radius: 12px;
     1404        font-size: 16px;
     1405        font-weight: 600;
     1406        cursor: pointer;
     1407        transition: all 0.3s ease;
     1408        min-width: 120px;
     1409    }
     1410
     1411    .askeet-modal-btn-primary {
     1412        background: linear-gradient(135deg, #005a9e 0%, #0088cc 100%);
     1413        color: white;
     1414        box-shadow: 0 4px 12px rgba(0, 90, 158, 0.3);
     1415    }
     1416
     1417    .askeet-modal-btn-primary:hover {
     1418        transform: translateY(-2px);
     1419        box-shadow: 0 6px 20px rgba(0, 90, 158, 0.4);
     1420    }
     1421
     1422    .askeet-modal-btn-secondary {
     1423        background: #f5f5f5;
     1424        color: #666;
     1425        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
     1426    }
     1427
     1428    .askeet-modal-btn-secondary:hover {
     1429        background: #e0e0e0;
     1430        transform: translateY(-2px);
     1431    }
     1432    </style>
     1433
    12441434    <script>
    12451435    jQuery(document).ready(function($) {
    12461436        // Track current billing mode (monthly or yearly)
    12471437        let currentBillingMode = 'monthly';
     1438
     1439        // ========================================
     1440        // MODERN MODAL SYSTEM
     1441        // ========================================
     1442
     1443        /**
     1444         * Show modern modal with different types
     1445         * @param {string} type - 'success', 'error', or 'loading'
     1446         * @param {string} title - Modal title
     1447         * @param {string} message - Modal message
     1448         * @param {Object} options - Additional options (buttons, callbacks)
     1449         */
     1450        function showModal(type, title, message, options = {}) {
     1451            const overlay = $('#askeet-modal-overlay');
     1452            const modal = $('.askeet-modal');
     1453            const icon = $('#askeet-modal-icon');
     1454            const titleEl = $('#askeet-modal-title');
     1455            const messageEl = $('#askeet-modal-message');
     1456            const actionsEl = $('#askeet-modal-actions');
     1457
     1458            // Reset modal classes and content
     1459            icon.removeClass('success error loading').addClass(type);
     1460            titleEl.text(title);
     1461            messageEl.text(message);
     1462
     1463            // Set icon content based on type
     1464            if (type === 'success') {
     1465                icon.html('✓');
     1466            } else if (type === 'error') {
     1467                icon.html('✕');
     1468            } else if (type === 'loading') {
     1469                icon.html(''); // Spinner is CSS-based
     1470            }
     1471
     1472            // Configure buttons
     1473            actionsEl.empty();
     1474
     1475            if (type === 'loading') {
     1476                // No buttons for loading state
     1477            } else {
     1478                // Primary button
     1479                const primaryBtn = $('<button>')
     1480                    .addClass('askeet-modal-btn askeet-modal-btn-primary')
     1481                    .text(options.primaryText || 'OK')
     1482                    .on('click', function() {
     1483                        hideModal();
     1484                        if (options.onPrimary) options.onPrimary();
     1485                    });
     1486                actionsEl.append(primaryBtn);
     1487
     1488                // Secondary button (optional)
     1489                if (options.secondaryText) {
     1490                    const secondaryBtn = $('<button>')
     1491                        .addClass('askeet-modal-btn askeet-modal-btn-secondary')
     1492                        .text(options.secondaryText)
     1493                        .on('click', function() {
     1494                            hideModal();
     1495                            if (options.onSecondary) options.onSecondary();
     1496                        });
     1497                    actionsEl.prepend(secondaryBtn);
     1498                }
     1499            }
     1500
     1501            // Show modal with animation
     1502            overlay.addClass('active');
     1503
     1504            // Close on overlay click (except for loading)
     1505            if (type !== 'loading') {
     1506                overlay.off('click').on('click', function(e) {
     1507                    if ($(e.target).is('#askeet-modal-overlay')) {
     1508                        hideModal();
     1509                    }
     1510                });
     1511            }
     1512        }
     1513
     1514        /**
     1515         * Hide modal with animation
     1516         */
     1517        function hideModal() {
     1518            const overlay = $('#askeet-modal-overlay');
     1519            overlay.removeClass('active');
     1520        }
     1521
     1522        /**
     1523         * Show success modal
     1524         */
     1525        function showSuccess(title, message, callback) {
     1526            showModal('success', title, message, {
     1527                primaryText: '<?php echo esc_js(__('Got it!', 'askeet')); ?>',
     1528                onPrimary: callback
     1529            });
     1530        }
     1531
     1532        /**
     1533         * Show error modal
     1534         */
     1535        function showError(title, message, callback) {
     1536            showModal('error', title, message, {
     1537                primaryText: '<?php echo esc_js(__('Try Again', 'askeet')); ?>',
     1538                onPrimary: callback
     1539            });
     1540        }
     1541
     1542        /**
     1543         * Show loading modal
     1544         */
     1545        function showLoading(message = '<?php echo esc_js(__('Processing...', 'askeet')); ?>') {
     1546            showModal('loading', '<?php echo esc_js(__('Please Wait', 'askeet')); ?>', message);
     1547        }
     1548
     1549        // ========================================
     1550        // END MODAL SYSTEM
     1551        // ========================================
    12481552
    12491553        // Handle billing toggle (monthly/yearly)
     
    12801584            const btn = $(this);
    12811585            const originalText = btn.html();
     1586            const currentPlan = '<?php echo esc_js($plan_code); ?>';
    12821587
    12831588            // Get the correct plan based on billing mode
     
    12891594            }
    12901595
     1596            console.log('Current plan:', currentPlan);
    12911597            console.log('Selected plan:', plan, 'Billing mode:', currentBillingMode);
    12921598
     1599            // Disable button
    12931600            btn.prop('disabled', true).html('<?php echo esc_js(__('Processing...', 'askeet')); ?>');
    12941601
    1295             $.ajax({
    1296                 url: '<?php echo esc_js(askeet_get_api_url()); ?>/create-checkout-session',
    1297                 type: 'POST',
    1298                 contentType: 'application/json',
    1299                 data: JSON.stringify({
     1602            // Determine if user has an active paid subscription
     1603            const hasPaidSubscription = currentPlan !== 'free' && currentPlan !== '';
     1604
     1605            // Show loading modal
     1606            if (hasPaidSubscription) {
     1607                showLoading('<?php echo esc_js(__('Updating your subscription... Please wait.', 'askeet')); ?>');
     1608            } else {
     1609                showLoading('<?php echo esc_js(__('Creating checkout session... Redirecting to Stripe.', 'askeet')); ?>');
     1610            }
     1611
     1612            // Choose the correct endpoint
     1613            let apiEndpoint, requestData;
     1614
     1615            if (hasPaidSubscription) {
     1616                // User has active subscription → UPGRADE existing subscription
     1617                console.log('Using /upgrade-subscription endpoint (modifying existing subscription)');
     1618                apiEndpoint = '<?php echo esc_js(askeet_get_api_url()); ?>/upgrade-subscription';
     1619                requestData = {
     1620                    install_id: '<?php echo esc_js($install_id); ?>',
     1621                    plan: plan.toString()
     1622                };
     1623            } else {
     1624                // User is on free plan → CREATE new subscription
     1625                console.log('Using /create-checkout-session endpoint (creating new subscription)');
     1626                apiEndpoint = '<?php echo esc_js(askeet_get_api_url()); ?>/create-checkout-session';
     1627                requestData = {
    13001628                    install_id: '<?php echo esc_js($install_id); ?>',
    13011629                    plan: plan.toString(),
    13021630                    success_url: '<?php echo esc_js($success_url); ?>',
    13031631                    cancel_url: '<?php echo esc_js($cancel_url); ?>'
    1304                 }),
     1632                };
     1633            }
     1634
     1635            $.ajax({
     1636                url: apiEndpoint,
     1637                type: 'POST',
     1638                contentType: 'application/json',
     1639                data: JSON.stringify(requestData),
    13051640                success: function(response) {
    1306                     if (response.checkout_url) {
    1307                         window.location.href = response.checkout_url;
     1641                    if (hasPaidSubscription) {
     1642                        // Upgrade response - reload page to show new plan
     1643                        if (response.success) {
     1644                            hideModal();
     1645                            showSuccess(
     1646                                '<?php echo esc_js(__('Success!', 'askeet')); ?>',
     1647                                '<?php echo esc_js(__('Your subscription has been updated successfully. The page will reload to show your new plan.', 'askeet')); ?>',
     1648                                function() {
     1649                                    window.location.reload();
     1650                                }
     1651                            );
     1652                            // Auto reload after 2 seconds
     1653                            setTimeout(function() {
     1654                                window.location.reload();
     1655                            }, 2000);
     1656                        } else {
     1657                            hideModal();
     1658                            showError(
     1659                                '<?php echo esc_js(__('Upgrade Failed', 'askeet')); ?>',
     1660                                (response.error || '<?php echo esc_js(__('An unknown error occurred. Please try again.', 'askeet')); ?>'),
     1661                                function() {
     1662                                    btn.prop('disabled', false).html(originalText);
     1663                                }
     1664                            );
     1665                            btn.prop('disabled', false).html(originalText);
     1666                        }
    13081667                    } else {
    1309                         alert('<?php echo esc_js(__('Error: No checkout URL received.', 'askeet')); ?>');
    1310                         btn.prop('disabled', false).html(originalText);
     1668                        // Checkout session response - redirect to Stripe
     1669                        if (response.checkout_url) {
     1670                            hideModal();
     1671                            showSuccess(
     1672                                '<?php echo esc_js(__('Redirecting to Checkout', 'askeet')); ?>',
     1673                                '<?php echo esc_js(__('Your checkout session is ready. Redirecting you to Stripe...', 'askeet')); ?>',
     1674                                function() {
     1675                                    window.location.href = response.checkout_url;
     1676                                }
     1677                            );
     1678                            // Auto redirect after 1 second
     1679                            setTimeout(function() {
     1680                                window.location.href = response.checkout_url;
     1681                            }, 1000);
     1682                        } else {
     1683                            hideModal();
     1684                            showError(
     1685                                '<?php echo esc_js(__('Checkout Failed', 'askeet')); ?>',
     1686                                '<?php echo esc_js(__('Could not create checkout session. Please try again or contact support.', 'askeet')); ?>',
     1687                                function() {
     1688                                    btn.prop('disabled', false).html(originalText);
     1689                                }
     1690                            );
     1691                            btn.prop('disabled', false).html(originalText);
     1692                        }
    13111693                    }
    13121694                },
    1313                 error: function() {
    1314                     alert('<?php echo esc_js(__('Error creating checkout session. Please try again.', 'askeet')); ?>');
     1695                error: function(xhr) {
     1696                    hideModal();
     1697                    const errorMsg = xhr.responseJSON && xhr.responseJSON.error ? xhr.responseJSON.error : '<?php echo esc_js(__('Network error. Please check your connection and try again.', 'askeet')); ?>';
     1698                    showError(
     1699                        '<?php echo esc_js(__('Request Failed', 'askeet')); ?>',
     1700                        errorMsg,
     1701                        function() {
     1702                            btn.prop('disabled', false).html(originalText);
     1703                        }
     1704                    );
    13151705                    btn.prop('disabled', false).html(originalText);
    13161706                }
Note: See TracChangeset for help on using the changeset viewer.