# easy-invoice/2.1.20/assets/js/confirmation-modal.js

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.1.20. 525 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.1.20/code/assets/js/confirmation-modal.js
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.1.20/raw/assets/js/confirmation-modal.js
- Modified: 2026-04-11T13:58:14+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.1.20/code/assets/js/confirmation-modal.js#L10-L20`.

```javascript
/**
 * Generic Confirmation Modal
 * 
 * A reusable confirmation modal that can be used across all EasyInvoice pages.
 * 
 * @package EasyInvoice
 * @since 1.0.0
 * 
 * USAGE EXAMPLES:
 * 
 * 1. Regular confirmation dialog:
 *    EasyInvoiceConfirmation.show({
 *        title: 'Delete Item',
 *        message: 'Are you sure you want to delete this item?',
 *        confirmText: 'Delete',
 *        confirmClass: 'bg-red-600 hover:bg-red-700',
 *        onConfirm: function() { // delete logic }
 *    });
 * 
 * 2. Quick confirmation for common actions:
 *    EasyInvoiceConfirmation.confirmAction('delete', 'invoice INV-001', function() {
 *        // delete logic
 *    });
 * 
 * 3. Generic upgrade dialog for premium features:
 *    EasyInvoiceConfirmation.showFeatureUpgrade('Quote Duplication');
 * 
 * 4. Custom upgrade dialog:
 *    EasyInvoiceConfirmation.showUpgradeDialog({
 *        featureName: 'Custom Feature',
 *        description: 'Custom description of the feature benefits',
 *        onUpgrade: function() { window.open('https://upgrade-url.com', '_blank'); },
 *        onCancel: function() { }
 *    });
 * 
 * AVAILABLE PREMIUM FEATURES:
 * - Quote Duplication
 * - Advanced Reporting
 * - Custom Branding
 * - Bulk Operations
 * - Email Templates
 * - Payment Integration
 * - Client Portal
 * - Recurring Invoices
 */

(function($) {
    'use strict';

    // Create the modal HTML if it doesn't exist
    if ($('#easy-invoice-confirmation-modal').length === 0) {
        const modalHTML = `
            <div id="easy-invoice-confirmation-modal" class="fixed z-50 inset-0 overflow-y-auto hidden">
                <div class="flex items-center justify-center min-h-screen px-4">
                    <div class="fixed inset-0 transition-opacity" aria-hidden="true">
                        <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
                    </div>
                    <div class="bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:max-w-lg w-full z-50">
                        <div class="px-6 py-6">
                            <div class="flex items-center mb-4">
                                <div class="flex-shrink-0">
                                    <svg class="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
                                    </svg>
                                </div>
                                <div class="ml-3">
                                    <h3 class="text-lg font-medium text-gray-900" id="confirmation-title">Confirm Action</h3>
                                </div>
                            </div>
                            <div class="mt-2">
                                <p class="text-sm text-gray-500" id="confirmation-message">Are you sure you want to perform this action?</p>
                            </div>
                            <div class="mt-6 flex justify-end space-x-3">
                                <button type="button" id="confirmation-cancel" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500">
                                    Cancel
                                </button>
                                <button type="button" id="confirmation-confirm" class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500">
                                    Confirm
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        `;
        $('body').append(modalHTML);
    }

    // Global confirmation modal object
    window.EasyInvoiceConfirmation = {
        /**
         * Show confirmation modal
         * 
         * @param {Object} options Configuration options
         * @param {string} options.title Modal title
         * @param {string} options.message Modal message
         * @param {string} options.confirmText Confirm button text (default: "Confirm")
         * @param {string} options.cancelText Cancel button text (default: "Cancel")
         * @param {string} options.confirmClass CSS class for confirm button (default: "bg-red-600 hover:bg-red-700")
         * @param {Function} options.onConfirm Callback function when confirmed
         * @param {Function} options.onCancel Callback function when cancelled
         */
        show: function(options) {
            const defaults = {
                title: 'Confirm Action',
                message: 'Are you sure you want to perform this action?',
                confirmText: 'Confirm',
                cancelText: 'Cancel',
                confirmClass: 'bg-red-600 hover:bg-red-700',
                onConfirm: function() {},
                onCancel: function() {}
            };

            const config = $.extend({}, defaults, options);

            // Update modal content
            $('#confirmation-title').text(config.title);
            $('#confirmation-message').text(config.message);
            $('#confirmation-confirm').text(config.confirmText);
            $('#confirmation-cancel').text(config.cancelText);
            
            // Update confirm button styling
            var btnClass = config.confirmClass && config.confirmClass.trim() !== '' 
                ? config.confirmClass 
                : 'bg-red-600 hover:bg-red-700';
            $('#confirmation-confirm')
                .removeClass()
                .addClass('px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500 ' + btnClass);

            // Store callbacks
            $('#easy-invoice-confirmation-modal').data('onConfirm', config.onConfirm);
            $('#easy-invoice-confirmation-modal').data('onCancel', config.onCancel);

            // Show modal
            $('#easy-invoice-confirmation-modal').removeClass('hidden');
        },

        /**
         * Show upgrade to pro modal - Special encouraging dialog
         * 
         * @param {Object} options Configuration options
         * @param {string} options.featureName Name of the premium feature (e.g., "Quote Duplication")
         * @param {string} options.description Custom description (optional)
         * @param {Function} options.onUpgrade Callback function when user clicks upgrade
         * @param {Function} options.onCancel Callback function when user cancels
         */
        showUpgradeDialog: function(options) {
            const defaults = {
                featureName: 'Premium Feature',
                description: '',
                onUpgrade: function() {
                    // Default upgrade action - redirect to upgrade page
                    window.open('https://matrixaddons.com/plugins/easy-invoice/#pricing', '_blank');
                },
                onCancel: function() {}
            };

            const config = $.extend({}, defaults, options);

            // Create upgrade modal HTML if it doesn't exist
            if ($('#easy-invoice-upgrade-modal').length === 0) {
                const upgradeModalHTML = `
                    <div id="easy-invoice-upgrade-modal" class="fixed z-50 inset-0 overflow-y-auto hidden">
                        <div class="flex items-center justify-center min-h-screen px-4">
                            <div class="fixed inset-0 transition-opacity" aria-hidden="true">
                                <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
                            </div>
                            <div class="bg-gradient-to-br from-indigo-50 to-purple-50 rounded-lg overflow-hidden shadow-xl transform transition-all sm:max-w-lg w-full z-50 border border-indigo-200 relative">
                                <button type="button" id="upgrade-close" class="absolute top-4 right-4 text-gray-400 hover:text-gray-600 focus:outline-none" aria-label="Close">
                                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                                    </svg>
                                </button>
                                <div class="px-6 py-6">
                                    <!-- Header with premium icon -->
                                    <div class="flex items-center justify-center mb-4">
                                        <div class="flex-shrink-0">
                                            <div class="w-16 h-16 bg-purple-600 rounded-full flex items-center justify-center">
                                                <svg class="w-8 h-8 text-white" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                                    <path d="M12 8L15 13.2L18 10.5L17.3 14H6.7L6 10.5L9 13.2L12 8M12 4L8.5 10L3 5L5 16H19L21 5L15.5 10L12 4Z"/>
                                                </svg>
                                            </div>
                                        </div>
                                    </div>
                                    
                                    <!-- Title -->
                                    <div class="text-center mb-4">
                                        <h3 class="text-xl font-bold text-gray-900" id="upgrade-title">Unlock Premium Features</h3>
                                        <p class="text-sm text-indigo-600 font-medium mt-1" id="upgrade-feature">${config.featureName}</p>
                                    </div>
                                    
                                    <!-- Description -->
                                    <div class="text-center mb-6">
                                        <p class="text-sm text-gray-600" id="upgrade-description">
                                            ${config.description || `Upgrade to Easy Invoice Pro to unlock ${config.featureName} and many other premium features that will help you manage your business more efficiently.`}
                                        </p>
                                    </div>
                                    
                                    <!-- Benefits list -->
                                    <div class="bg-white rounded-lg p-4 mb-6 border border-indigo-100">
                                        <h4 class="text-sm font-semibold text-gray-900 mb-3">Why teams upgrade to Pro</h4>
                                        <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 text-sm text-gray-700">
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Advanced reporting & analytics</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Client Portal with secure online payments</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Partial payments & deposits</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Recurring invoices & subscriptions</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Payment gateways: Stripe, Square, Mollie, Bank Transfer</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Smart reminders & automated emails</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Custom branding, premium templates & PDF watermarking</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Unlimited quotes & invoices</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>CSV export & integrations-ready</span>
                                            </div>
                                            <div class="flex items-start">
                                                <svg class="w-4 h-4 text-green-500 mr-2 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
                                                <span>Priority support & automatic updates</span>
                                            </div>
                                        </div>
                                        <!-- Trust badges -->
                                        <div class="mt-4 flex flex-wrap items-center justify-center gap-3 text-xs text-gray-500">
                                            <span class="inline-flex items-center px-2 py-1 bg-gray-100 rounded">No coding required</span>
                                            <span class="inline-flex items-center px-2 py-1 bg-gray-100 rounded">Cancel anytime</span>
                                            <span class="inline-flex items-center px-2 py-1 bg-gray-100 rounded">Fast, friendly support</span>
                                        </div>
                                    </div>
                                    
                                    <!-- Action button -->
                                    <div class="flex flex-col space-y-3">
                                        <button type="button" id="upgrade-confirm" class="w-full px-4 py-3 bg-purple-600 text-white rounded-md hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 font-medium transition-all duration-200 transform hover:scale-105">
                                            <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path>
                                            </svg>
                                            Upgrade to Pro
                                        </button>
                                            <p class="text-[11px] text-gray-500 text-center">You can activate your license instantly after purchase.</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                `;
                
                $('body').append(upgradeModalHTML);
                
                // Event handlers for upgrade modal
                $(document).on('click', '#upgrade-confirm', function() {
                    const modal = $('#easy-invoice-upgrade-modal');
                    const onUpgrade = modal.data('onUpgrade');
                    
                    if (typeof onUpgrade === 'function') {
                        onUpgrade();
                    }
                    
                    EasyInvoiceConfirmation.hideUpgradeDialog();
                });
                
                // Close button handler
                $(document).on('click', '#upgrade-close', function() {
                    const modal = $('#easy-invoice-upgrade-modal');
                    const onCancel = modal.data('onCancel');
                    if (typeof onCancel === 'function') {
                        onCancel();
                    }
                    EasyInvoiceConfirmation.hideUpgradeDialog();
                });
                
                // Close modal on backdrop click
                $(document).on('click', '#easy-invoice-upgrade-modal', function(e) {
                    if (e.target === this) {
                        EasyInvoiceConfirmation.hideUpgradeDialog();
                    }
                });
                
                // Close modal on escape key
                $(document).on('keydown', function(e) {
                    if (e.key === 'Escape' && !$('#easy-invoice-upgrade-modal').hasClass('hidden')) {
                        EasyInvoiceConfirmation.hideUpgradeDialog();
                    }
                });
            }
            
            // Update modal content
            $('#upgrade-feature').text(config.featureName);
            $('#upgrade-description').html(config.description || `Upgrade to Easy Invoice Pro to unlock ${config.featureName} and many other premium features that will help you manage your business more efficiently.`);
            
            // Store callbacks
            $('#easy-invoice-upgrade-modal').data('onUpgrade', config.onUpgrade);
            $('#easy-invoice-upgrade-modal').data('onCancel', config.onCancel);
            
            // Show modal
            $('#easy-invoice-upgrade-modal').removeClass('hidden');
        },

        /**
         * Quick upgrade dialog for common premium features
         * 
         * @param {string} featureName Name of the premium feature
         * @param {string} customDescription Custom description (optional)
         * @param {string} upgradeUrl Custom upgrade URL (optional)
         */
        showFeatureUpgrade: function(featureName, customDescription, upgradeUrl) {
            const featureConfigs = {
                'Quote Duplication': {
                    description: 'Create copies of your quotes instantly to save time and maintain consistency across similar projects. Perfect for recurring clients and template-based work.',
                    icon: 'copy'
                },
                'Invoice Duplication': {
                    description: 'Create copies of your invoices instantly to save time and maintain consistency across similar projects. Perfect for recurring clients and template-based work.',
                    icon: 'copy'
                },
                'Advanced Reporting': {
                    description: 'Get detailed insights into your business performance with advanced analytics, charts, and customizable reports to make data-driven decisions.',
                    icon: 'chart'
                },
                'Custom Branding': {
                    description: 'Add your company logo, colors, and branding to all your quotes and invoices for a professional, branded appearance.',
                    icon: 'paint'
                },
                'Bulk Operations': {
                    description: 'Perform actions on multiple quotes or invoices at once to save time and streamline your workflow.',
                    icon: 'bulk'
                },
                'Email Templates': {
                    description: 'Create and customize professional email templates for sending quotes and invoices to clients.',
                    icon: 'email'
                },
                'Payment Integration': {
                    description: 'Accept online payments directly through your quotes and invoices with popular payment gateways.',
                    icon: 'payment'
                },
                'Client Portal': {
                    description: 'Give your clients access to view and manage their quotes and invoices through a secure client portal.',
                    icon: 'portal'
                },
                'Recurring Invoices': {
                    description: 'Automate your billing with recurring invoices that are sent automatically on your schedule.',
                    icon: 'recurring'
                }
            };

            const config = featureConfigs[featureName] || {
                description: customDescription || `Upgrade to Easy Invoice Pro to unlock ${featureName} and many other premium features.`,
                icon: 'star'
            };

            this.showUpgradeDialog({
                featureName: featureName,
                description: config.description,
                onUpgrade: function() {
                    // Redirect to upgrade page
                    window.open(upgradeUrl || 'https://matrixaddons.com/plugins/easy-invoice/#pricing', '_blank');
                },
                onCancel: function() {
                    // User chose to skip for now
                }
            });
        },

        /**
         * Hide upgrade dialog
         */
        hideUpgradeDialog: function() {
            $('#easy-invoice-upgrade-modal').addClass('hidden');
        },

        /**
         * Hide confirmation modal
         */
        hide: function() {
            $('#easy-invoice-confirmation-modal').addClass('hidden');
        },

        /**
         * Send invoice or quote by email — uses easyInvoice.i18n when available.
         *
         * @param {'invoice'|'quote'} kind Document type
         * @param {Function} onConfirm Called when user confirms
         */
        confirmSendDocument: function(kind, onConfirm) {
            var i18n = (window.easyInvoice && window.easyInvoice.i18n) ? window.easyInvoice.i18n : {};
            var isQuote = kind === 'quote';
            var title = isQuote
                ? (i18n.confirm_send_quote_title || 'Send quote by email')
                : (i18n.confirm_send_invoice_title || 'Send invoice by email');
            var message = isQuote
                ? (i18n.confirm_send_quote_message || 'The quote will be emailed to the client using your template.')
                : (i18n.confirm_send_invoice_message || 'The invoice will be emailed to the client using your template.');
            var confirmText = i18n.confirm_send_confirm || i18n.send_invoice || 'Send';
            var cancelText = i18n.confirm_cancel || i18n.cancel || 'Cancel';

            this.show({
                title: title,
                message: message,
                confirmText: confirmText,
                cancelText: cancelText,
                confirmClass: 'bg-indigo-600 hover:bg-indigo-700',
                onConfirm: typeof onConfirm === 'function' ? onConfirm : function() {}
            });
        },

        /**
         * Quick confirmation for common actions
         * 
         * @param {string} action Action type (delete, trash, draft, etc.)
         * @param {string} itemName Name of the item being acted upon
         * @param {Function} onConfirm Callback function when confirmed
         */
        confirmAction: function(action, itemName, onConfirm) {
            const actionConfigs = {
                'delete': {
                    title: 'Delete Permanently',
                    message: `Are you sure you want to permanently delete ${itemName}? This action cannot be undone.`,
                    confirmText: 'Delete Permanently',
                    confirmClass: 'bg-red-600 hover:bg-red-700'
                },
                'trash': {
                    title: 'Move to Trash',
                    message: `Are you sure you want to move ${itemName} to trash?`,
                    confirmText: 'Move to Trash',
                    confirmClass: 'bg-orange-600 hover:bg-orange-700'
                },
                'draft': {
                    title: 'Move to Draft',
                    message: `Are you sure you want to move ${itemName} to draft?`,
                    confirmText: 'Move to Draft',
                    confirmClass: 'bg-gray-600 hover:bg-gray-700'
                },
                'publish': {
                    title: 'Publish',
                    message: `Are you sure you want to publish ${itemName}?`,
                    confirmText: 'Publish',
                    confirmClass: 'bg-green-600 hover:bg-green-700'
                },
                'restore': {
                    title: 'Restore',
                    message: `Are you sure you want to restore ${itemName}?`,
                    confirmText: 'Restore',
                    confirmClass: 'bg-green-600 hover:bg-green-700'
                }
            };

            const config = actionConfigs[action] || {
                title: 'Confirm Action',
                message: `Are you sure you want to ${action} ${itemName}?`,
                confirmText: 'Confirm',
                confirmClass: 'bg-red-600 hover:bg-red-700'
            };

            this.show({
                title: config.title,
                message: config.message,
                confirmText: config.confirmText,
                confirmClass: config.confirmClass,
                onConfirm: onConfirm
            });
        }
    };

    // Event handlers
    $(document).ready(function() {
        // Confirm button click
        $(document).on('click', '#confirmation-confirm', function() {
            const modal = $('#easy-invoice-confirmation-modal');
            const onConfirm = modal.data('onConfirm');
            
            if (typeof onConfirm === 'function') {
                onConfirm();
            }
            
            EasyInvoiceConfirmation.hide();
        });

        // Cancel button click
        $(document).on('click', '#confirmation-cancel', function() {
            const modal = $('#easy-invoice-confirmation-modal');
            const onCancel = modal.data('onCancel');
            
            if (typeof onCancel === 'function') {
                onCancel();
            }
            
            EasyInvoiceConfirmation.hide();
        });

        // Close modal on backdrop click
        $(document).on('click', '#easy-invoice-confirmation-modal', function(e) {
            if (e.target === this) {
                EasyInvoiceConfirmation.hide();
            }
        });

        // Close modal on escape key
        $(document).on('keydown', function(e) {
            if (e.key === 'Escape' && !$('#easy-invoice-confirmation-modal').hasClass('hidden')) {
                EasyInvoiceConfirmation.hide();
            }
        });
    });

})(jQuery); 
```
