Changeset 3284080
- Timestamp:
- 04/29/2025 12:00:29 PM (11 months ago)
- Location:
- quickbundles/trunk
- Files:
-
- 4 added
- 5 edited
-
assets/css/consent-modal.css (modified) (1 diff)
-
assets/images (added)
-
assets/images/logo.svg (added)
-
assets/js/consent-modal.js (modified) (1 diff)
-
includes/class-qbnd-consent-modal.php (added)
-
includes/class-qbnd-init.php (modified) (3 diffs)
-
includes/class-qbnd-tracking.php (added)
-
quickbundles.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
quickbundles/trunk/assets/css/consent-modal.css
r3283925 r3284080 1 .quickbundles-modal { 2 display: none; 1 /* Modal Container */ 2 .qbnd-modal { 3 3 position: fixed; 4 z-index: 999999;4 top: 0; 5 5 left: 0; 6 top: 0;7 6 width: 100%; 8 7 height: 100%; 9 background-color: rgba(0, 0, 0, 0.5); 8 background: rgba(0, 0, 0, 0.5); 9 z-index: 999999; 10 display: none; 11 align-items: center; 12 justify-content: center; 13 opacity: 0; 14 transition: opacity 0.3s ease-in-out; 10 15 } 11 16 12 .quickbundles-modal-content { 13 background-color: #fff; 14 margin: 10% auto; 15 padding: 20px; 16 border-radius: 8px; 17 max-width: 600px; 18 position: relative; 19 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 17 .qbnd-modal.show { 18 display: flex; 19 opacity: 1; 20 20 } 21 21 22 .modal-header { 23 margin-bottom: 20px; 22 /* Modal Content */ 23 .qbnd-modal-content { 24 max-width: 460px; 25 width: 90%; 26 background: #fff; 27 border-radius: 8px; 28 box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1); 29 transform: translateY(20px); 30 transition: transform 0.3s ease-in-out; 31 margin: 20px; 32 } 33 34 .qbnd-modal.show .qbnd-modal-content { 35 transform: translateY(0); 36 } 37 38 /* Header */ 39 .qbnd-modal .modal-header { 40 padding: 24px 24px 16px; 41 } 42 43 .qbnd-modal .logo-title-wrapper { 44 display: flex; 45 align-items: center; 46 gap: 12px; 47 } 48 49 .qbnd-modal .logo-title-wrapper img { 50 width: 32px; 51 height: 32px; 52 } 53 54 .qbnd-modal .logo-title-wrapper h2 { 55 margin: 0; 56 font-size: 18px; 57 color: #1d2327; 58 font-weight: 500; 59 } 60 61 /* Body */ 62 .qbnd-modal .modal-body { 63 padding: 0 24px 24px; 64 } 65 66 .qbnd-modal .consent-benefits { 67 display: flex; 68 flex-direction: column; 69 gap: 16px; 70 } 71 72 .qbnd-modal .benefit-item { 73 display: flex; 74 align-items: center; 75 gap: 12px; 76 padding: 12px; 77 background: #f0f7ff; 78 border-radius: 6px; 79 } 80 81 .qbnd-modal .benefit-icon { 82 font-size: 20px; 83 min-width: 24px; 24 84 text-align: center; 25 85 } 26 86 27 .logo-title-wrapper h2 { 28 margin: 0; 29 color: #23282d; 30 font-size: 24px; 87 .qbnd-modal .benefit-text { 88 flex: 1; 89 font-size: 14px; 90 color: #1d2327; 91 line-height: 1.4; 31 92 } 32 93 33 .modal-body { 34 margin-bottom: 30px; 94 /* Footer */ 95 .qbnd-modal .modal-footer { 96 padding: 0 24px 24px; 97 display: flex; 98 flex-direction: column; 99 gap: 8px; 35 100 } 36 101 37 .consent-benefits { 38 display: flex; 39 flex-direction: column; 40 gap: 15px; 102 /* Buttons */ 103 .qbnd-modal .button { 104 padding: 8px 16px; 105 height: auto; 106 width: 100%; 107 font-size: 14px; 108 font-weight: 500; 109 text-align: center; 110 border-radius: 4px; 111 cursor: pointer; 112 transition: all 0.2s ease; 113 border: none; 41 114 } 42 115 43 .benefit-item { 44 display: flex; 45 align-items: center; 46 gap: 10px; 47 } 48 49 .benefit-icon { 50 font-size: 24px; 51 } 52 53 .benefit-text { 54 font-size: 16px; 55 color: #444; 56 } 57 58 .modal-footer { 59 display: flex; 60 justify-content: center; 61 gap: 10px; 62 } 63 64 .modal-footer button { 65 min-width: 120px; 66 text-align: center; 67 } 68 69 #quickbundles-consent-yes { 70 background-color: #2271b1; 71 border-color: #2271b1; 116 .qbnd-modal .button-primary { 117 background: #2271b1; 72 118 color: #fff; 73 119 } 74 120 75 #quickbundles-consent-yes:hover { 76 background-color: #135e96; 77 border-color: #135e96; 121 .qbnd-modal .button-primary:hover { 122 background: #135e96; 78 123 } 79 124 80 #quickbundles-consent-no { 125 .qbnd-modal .button-secondary { 126 background: transparent; 81 127 color: #2271b1; 82 border-color: #2271b1;83 128 } 84 129 85 #quickbundles-consent-no:hover { 130 .qbnd-modal .button-secondary:hover { 131 text-decoration: none; 132 background: transparent; 86 133 color: #135e96; 87 border-color: #135e96;88 134 } 135 136 /* Mobile Responsiveness */ 137 @media screen and (max-width: 480px) { 138 .qbnd-modal-content { 139 margin: 16px; 140 } 141 142 .qbnd-modal .modal-header, 143 .qbnd-modal .modal-body, 144 .qbnd-modal .modal-footer { 145 padding-left: 16px; 146 padding-right: 16px; 147 } 148 } 149 150 /* RTL Support */ 151 .rtl .qbnd-modal .logo-title-wrapper { 152 flex-direction: row-reverse; 153 } 154 155 .rtl .qbnd-modal .benefit-item { 156 flex-direction: row-reverse; 157 } 158 159 /* Accessibility */ 160 .qbnd-modal .button:focus { 161 outline: 2px solid #2271b1; 162 outline-offset: 2px; 163 box-shadow: none; 164 } -
quickbundles/trunk/assets/js/consent-modal.js
r3283925 r3284080 1 jQuery(document).ready(function ($) { 2 // Show modal on page load 3 $('#quickbundles-consent-modal').show(); 1 (function ($) { 2 'use strict'; 4 3 5 // Handle consent button clicks 6 $('#quickbundles-consent-yes, #quickbundles-consent-no').on('click', function () { 7 const consent = $(this).attr('id') === 'quickbundles-consent-yes' ? 'allowed' : 'denied'; 4 // Modal handling class 5 class ConsentModal { 6 constructor() { 7 this.$modal = $('#qbnd-consent-modal'); 8 this.$content = this.$modal.find('.qbnd-modal-content'); 9 this.$allowBtn = $('#qbnd-consent-yes'); 10 this.$denyBtn = $('#qbnd-consent-no'); 8 11 9 $.ajax({ 10 url: quickBundlesConsent.ajaxurl, 11 type: 'POST', 12 data: { 13 action: 'quickbundles_handle_consent', 14 consent: consent, 15 nonce: quickBundlesConsent.nonce 16 }, 17 success: function (response) { 18 if (response.success) { 19 alert(response.data.message); 20 } else { 21 alert(quickBundlesConsent.i18n.error); 12 this.bindEvents(); 13 this.showModal(); 14 } 15 16 bindEvents() { 17 this.$allowBtn.on('click', () => this.handleConsent('allowed')); 18 this.$denyBtn.on('click', () => this.handleConsent('denied')); 19 20 // Close modal on escape key 21 $(document).on('keyup', (e) => { 22 if (e.key === 'Escape') { 23 this.hideModal(); 22 24 } 23 $('#quickbundles-consent-modal').hide(); 24 }, 25 error: function () { 26 alert(quickBundlesConsent.i18n.error); 27 $('#quickbundles-consent-modal').hide(); 28 } 29 }); 25 }); 26 27 // Prevent modal content clicks from bubbling 28 this.$content.on('click', (e) => e.stopPropagation()); 29 } 30 31 showModal() { 32 this.$modal.addClass('show'); 33 $('body').addClass('modal-open'); 34 } 35 36 hideModal() { 37 this.$modal.removeClass('show'); 38 $('body').removeClass('modal-open'); 39 40 setTimeout(() => { 41 this.$modal.hide(); 42 }, 300); 43 } 44 45 showNotice(message, type = 'success') { 46 const noticeClass = type === 'success' ? 'notice-success' : 'notice-error'; 47 const $notice = $('<div/>', { 48 class: `notice ${noticeClass} is-dismissible`, 49 html: `<p>${message}</p>` 50 }); 51 52 // Remove existing notices 53 $('.notice').remove(); 54 55 // Add new notice after the modal 56 this.$modal.after($notice); 57 58 // Auto dismiss after 3 seconds 59 setTimeout(() => { 60 $notice.fadeOut(() => $notice.remove()); 61 }, 3000); 62 } 63 64 handleConsent(consent) { 65 const self = this; 66 67 $.ajax({ 68 url: qbndConsent.ajaxurl, 69 type: 'POST', 70 data: { 71 action: 'qbnd_handle_consent', 72 consent: consent, 73 nonce: qbndConsent.nonce 74 }, 75 beforeSend: function () { 76 // Disable buttons during request 77 self.$allowBtn.prop('disabled', true); 78 self.$denyBtn.prop('disabled', true); 79 }, 80 success: function (response) { 81 if (response.success) { 82 self.showNotice( 83 consent === 'allowed' 84 ? qbndConsent.i18n.success 85 : response.data.message 86 ); 87 self.hideModal(); 88 } else { 89 self.showNotice(response.data.message, 'error'); 90 } 91 }, 92 error: function () { 93 self.showNotice(qbndConsent.i18n.error, 'error'); 94 }, 95 complete: function () { 96 // Re-enable buttons 97 self.$allowBtn.prop('disabled', false); 98 self.$denyBtn.prop('disabled', false); 99 } 100 }); 101 } 102 } 103 104 // Initialize on document ready 105 $(document).ready(function () { 106 new ConsentModal(); 30 107 }); 31 }); 108 109 })(jQuery); -
quickbundles/trunk/includes/class-qbnd-init.php
r3283925 r3284080 33 33 private function __construct() 34 34 { 35 $this->define_constants();35 // $this->define_constants(); // Removed - Defined in main plugin file 36 36 $this->init_hooks(); 37 37 } 38 38 39 39 /** 40 * Define plugin constants 40 * Define plugin constants - Removed 41 41 */ 42 private function define_constants(): void43 {44 define('QBND_VERSION', '1.0.0');45 define('QBND_PLUGIN_DIR', plugin_dir_path(dirname(__FILE__)));46 define('QBND_PLUGIN_URL', plugin_dir_url(dirname(__FILE__)));47 }42 // private function define_constants(): void 43 // { 44 // define('QBND_VERSION', '1.0.0'); 45 // define('QBND_PLUGIN_DIR', plugin_dir_path(dirname(__FILE__))); 46 // define('QBND_PLUGIN_URL', plugin_dir_url(dirname(__FILE__))); 47 // } 48 48 49 49 /** … … 104 104 if (is_admin()) { 105 105 require_once QBND_PLUGIN_DIR . 'includes/admin/class-qbnd-admin.php'; 106 require_once QBND_PLUGIN_DIR . 'includes/admin/class-qbnd-consent-modal.php';107 require_once QBND_PLUGIN_DIR . 'includes/admin/class-qbnd-tracking.php';106 // require_once QBND_PLUGIN_DIR . 'includes/admin/class-qbnd-consent-modal.php'; // Removed - Loaded in main plugin file 107 // require_once QBND_PLUGIN_DIR . 'includes/admin/class-qbnd-tracking.php'; // Removed - Loaded in main plugin file 108 108 } 109 109 … … 130 130 if (is_admin()) { 131 131 QBND_Admin::get_instance(); 132 QBND_Consent_Modal::get_instance();133 QBND_Tracking::get_instance();132 // QBND_Consent_Modal::get_instance(); // Removed - Initialized in main plugin file 133 // QBND_Tracking::get_instance(); // Removed - Initialized in main plugin file 134 134 } 135 135 -
quickbundles/trunk/quickbundles.php
r3283925 r3284080 4 4 * Plugin Name:QuickBundles 5 5 * Plugin URI:https://quickbundles.logiklabs.tech 6 * Description:Create compelling product bundles that drive sales and increase average order value. Transform your WooCommerce store with customizable bundles, dynamic pricing, and limited-time offers.6 * Description:Create compelling product bundles that drive sales and increase average order value. Transform your WooCommerce store with customizable bundles, dynamic pricing, flexible product options, bulk editing, and limited-time offers using an intuitive drag-and-drop builder. 7 7 * Version:1.0.0 8 8 * Author:LogikLabs … … 21 21 exit; // Exit if accessed directly. 22 22 } 23 24 // Define constants 25 define('QBND_PLUGIN_DIR', plugin_dir_path(__FILE__)); 26 define('QBND_PLUGIN_URL', plugin_dir_url(__FILE__)); 27 define('QBND_VERSION', '1.0.0'); 23 28 24 29 // Declare HPOS compatibility … … 71 76 // Set version 72 77 add_option('qbnd_version', '1.0.0'); 78 79 // Reset tracking options on activation 80 delete_option('qbnd_tracking_consent'); 81 delete_option('qbnd_tracking_consent_shown'); 82 delete_option('qbnd_installation_tracked'); 73 83 } 74 84 register_activation_hook(__FILE__, 'qbnd_activate'); … … 98 108 99 109 require_once plugin_dir_path(__FILE__) . 'includes/class-qbnd-init.php'; 110 111 // Load tracking classes 112 if (is_admin()) { 113 require_once QBND_PLUGIN_DIR . 'includes/class-qbnd-tracking.php'; 114 require_once QBND_PLUGIN_DIR . 'includes/class-qbnd-consent-modal.php'; 115 116 // Initialize tracking 117 QBND_Consent_Modal::get_instance(); 118 QBND_Tracking::get_instance(); 119 } 100 120 } 101 121 add_action('plugins_loaded', 'qbnd_load_core_files'); -
quickbundles/trunk/readme.txt
r3283954 r3284080 1 1 === QuickBundles - WooCommerce Product Bundles === 2 2 Contributors: logiklabs 3 Tags: woocommerce, product bundles, e-commerce m, marketing, analytics3 Tags: woocommerce, product bundles, e-commerce, shop, store, bulk discounts, product kits, combo deals, upsell, cross-sell, sales, marketing 4 4 Tested up to: 6.8 5 5 Stable tag: 1.0.0 … … 13 13 == Description == 14 14 15 [QuickBundles](https://quickbundles.logiklabs.tech/) transforms your WooCommerce store by enabling you to create compelling product bundles that drive sales and increase average order value. Whether you're running a flash sale, creating product kits, or offering combo deals, QuickBundles provides all the tools you need to succeed.16 15 17 Developed by [LogikLabs](https://logiklabs.tech/) - experts in innovative WordPress plugin solutions designed to elevate functionality, boost performance, and deliver seamless results for your website.16 * Description:Create compelling product bundles to boost sales & AOV. Features customizable bundles, dynamic pricing, timers & an intuitive builder for WooCommerce. 18 17 19 18 = Why Choose QuickBundles? =
Note: See TracChangeset
for help on using the changeset viewer.