Plugin Directory

Changeset 3284080


Ignore:
Timestamp:
04/29/2025 12:00:29 PM (11 months ago)
Author:
logiklabs
Message:

Tracking consent implementing

Location:
quickbundles/trunk
Files:
4 added
5 edited

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 {
    33  position: fixed;
    4   z-index: 999999;
     4  top: 0;
    55  left: 0;
    6   top: 0;
    76  width: 100%;
    87  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;
    1015}
    1116
    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;
    2020}
    2121
    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;
    2484  text-align: center;
    2585}
    2686
    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;
    3192}
    3293
    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;
    35100}
    36101
    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;
    41114}
    42115
    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;
    72118  color: #fff;
    73119}
    74120
    75 #quickbundles-consent-yes:hover {
    76   background-color: #135e96;
    77   border-color: #135e96;
     121.qbnd-modal .button-primary:hover {
     122  background: #135e96;
    78123}
    79124
    80 #quickbundles-consent-no {
     125.qbnd-modal .button-secondary {
     126  background: transparent;
    81127  color: #2271b1;
    82   border-color: #2271b1;
    83128}
    84129
    85 #quickbundles-consent-no:hover {
     130.qbnd-modal .button-secondary:hover {
     131  text-decoration: none;
     132  background: transparent;
    86133  color: #135e96;
    87   border-color: #135e96;
    88134}
     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';
    43
    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');
    811
    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();
    2224        }
    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();
    30107  });
    31 });
     108
     109})(jQuery);
  • quickbundles/trunk/includes/class-qbnd-init.php

    r3283925 r3284080  
    3333  private function __construct()
    3434  {
    35     $this->define_constants();
     35    // $this->define_constants(); // Removed - Defined in main plugin file
    3636    $this->init_hooks();
    3737  }
    3838
    3939  /**
    40    * Define plugin constants
     40   * Define plugin constants - Removed
    4141   */
    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   }
     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  // }
    4848
    4949  /**
     
    104104    if (is_admin()) {
    105105      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
    108108    }
    109109
     
    130130    if (is_admin()) {
    131131      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
    134134    }
    135135
  • quickbundles/trunk/quickbundles.php

    r3283925 r3284080  
    44 * Plugin Name:QuickBundles
    55 * 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.
    77 * Version:1.0.0
    88 * Author:LogikLabs
     
    2121  exit; // Exit if accessed directly.
    2222}
     23
     24// Define constants
     25define('QBND_PLUGIN_DIR', plugin_dir_path(__FILE__));
     26define('QBND_PLUGIN_URL', plugin_dir_url(__FILE__));
     27define('QBND_VERSION', '1.0.0');
    2328
    2429// Declare HPOS compatibility
     
    7176  // Set version
    7277  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');
    7383}
    7484register_activation_hook(__FILE__, 'qbnd_activate');
     
    98108
    99109  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  }
    100120}
    101121add_action('plugins_loaded', 'qbnd_load_core_files');
  • quickbundles/trunk/readme.txt

    r3283954 r3284080  
    11=== QuickBundles - WooCommerce Product Bundles ===
    22Contributors: logiklabs
    3 Tags: woocommerce, product bundles, e-commercem, marketing, analytics
     3Tags: woocommerce, product bundles, e-commerce, shop, store, bulk discounts, product kits, combo deals, upsell, cross-sell, sales, marketing
    44Tested up to: 6.8
    55Stable tag: 1.0.0
     
    1313== Description ==
    1414
    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.
    1615
    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.
    1817
    1918= Why Choose QuickBundles? =
Note: See TracChangeset for help on using the changeset viewer.