WP maple cart and page subtitle plugin upload

This commit is contained in:
Rodolfo Martinez 2025-12-12 18:30:26 -05:00
parent b3e87772ec
commit c85895d306
18 changed files with 5741 additions and 0 deletions

View file

@ -0,0 +1,355 @@
/**
* Maple Carts - Admin JavaScript.
*/
(function($) {
'use strict';
var MapleCartsAdmin = {
init: function() {
this.bindEvents();
},
bindEvents: function() {
// Delete cart.
$(document).on('click', '.maple-carts-delete-cart', this.deleteCart);
// View products modal.
$(document).on('click', '.maple-carts-view-products', this.showProducts);
// Template form.
$(document).on('submit', '#maple-carts-template-form', this.saveTemplate);
$(document).on('change', 'input[name="include_coupon"]', this.toggleCouponSettings);
// Delete template.
$(document).on('click', '.maple-carts-delete-template', this.deleteTemplate);
// Toggle template status.
$(document).on('click', '.maple-carts-toggle-template', this.toggleTemplate);
// Preview email.
$(document).on('click', '.maple-carts-preview-email', this.previewEmail);
// Test email.
$(document).on('click', '.maple-carts-test-email', this.openTestModal);
$(document).on('click', '.maple-carts-send-test', this.sendTestEmail);
// Modal close.
$(document).on('click', '.maple-carts-modal-close', this.closeModal);
$(document).on('click', '.maple-carts-modal', function(e) {
if ($(e.target).hasClass('maple-carts-modal')) {
MapleCartsAdmin.closeModal();
}
});
},
deleteCart: function(e) {
e.preventDefault();
if (!confirm(mapleCartsAdmin.confirmDelete)) {
return;
}
var $btn = $(this);
var cartId = $btn.data('id');
var $row = $btn.closest('tr');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_delete_cart',
nonce: mapleCartsAdmin.nonce,
cart_id: cartId
}, function(response) {
if (response.success) {
$row.fadeOut(300, function() {
$(this).remove();
});
} else {
alert('Error: ' + (response.data || 'Failed to delete cart'));
}
});
},
showProducts: function(e) {
e.preventDefault();
var cart = $(this).data('cart');
var html = '<table class="wp-list-table widefat">';
html += '<thead><tr><th>Product</th><th>Qty</th><th>Price</th></tr></thead><tbody>';
if (cart && cart.length) {
cart.forEach(function(item) {
html += '<tr>';
html += '<td>' + (item.name || 'Unknown Product') + '</td>';
html += '<td>' + (item.quantity || 1) + '</td>';
html += '<td>$' + (parseFloat(item.price) || 0).toFixed(2) + '</td>';
html += '</tr>';
});
} else {
html += '<tr><td colspan="3">No products</td></tr>';
}
html += '</tbody></table>';
$('#maple-carts-products-list').html(html);
$('#maple-carts-products-modal').show();
},
saveTemplate: function(e) {
e.preventDefault();
var $form = $(this);
var $btn = $form.find('button[type="submit"]');
var originalText = $btn.text();
$btn.text(mapleCartsAdmin.saving).prop('disabled', true);
// Get editor content.
var body = '';
if (typeof tinymce !== 'undefined' && tinymce.get('template-body')) {
body = tinymce.get('template-body').getContent();
} else {
body = $('#template-body').val();
}
var data = {
action: 'maple_carts_save_template',
nonce: mapleCartsAdmin.nonce,
id: $form.find('input[name="id"]').val(),
name: $form.find('input[name="name"]').val(),
subject: $form.find('input[name="subject"]').val(),
body: body,
delay_value: $form.find('input[name="delay_value"]').val(),
delay_unit: $form.find('select[name="delay_unit"]').val(),
is_active: $form.find('input[name="is_active"]').is(':checked') ? 1 : 0,
include_coupon: $form.find('input[name="include_coupon"]').is(':checked') ? 1 : 0,
coupon_type: $form.find('select[name="coupon_type"]').val(),
coupon_amount: $form.find('input[name="coupon_amount"]').val(),
coupon_expires_days: $form.find('input[name="coupon_expires_days"]').val()
};
$.post(mapleCartsAdmin.ajaxUrl, data, function(response) {
if (response.success) {
$btn.text(mapleCartsAdmin.saved);
setTimeout(function() {
window.location.href = 'admin.php?page=maple-carts-emails';
}, 500);
} else {
alert('Error: ' + (response.data || 'Failed to save template'));
$btn.text(originalText).prop('disabled', false);
}
});
},
toggleCouponSettings: function() {
var show = $(this).is(':checked');
$('.coupon-settings').toggle(show);
},
deleteTemplate: function(e) {
e.preventDefault();
if (!confirm(mapleCartsAdmin.confirmDelete)) {
return;
}
var $btn = $(this);
var templateId = $btn.data('id');
var $row = $btn.closest('tr');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_delete_template',
nonce: mapleCartsAdmin.nonce,
template_id: templateId
}, function(response) {
if (response.success) {
$row.fadeOut(300, function() {
$(this).remove();
});
} else {
alert('Error: ' + (response.data || 'Failed to delete template'));
}
});
},
toggleTemplate: function(e) {
e.preventDefault();
var $btn = $(this);
var templateId = $btn.data('id');
var isActive = $btn.data('active');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_toggle_template',
nonce: mapleCartsAdmin.nonce,
template_id: templateId,
active: isActive
}, function(response) {
if (response.success) {
$btn.data('active', response.data.is_active);
var $badge = $btn.find('.maple-carts-badge');
if (response.data.is_active) {
$badge.removeClass('badge-muted').addClass('badge-success').text('Active');
} else {
$badge.removeClass('badge-success').addClass('badge-muted').text('Inactive');
}
} else {
alert('Error: ' + (response.data || 'Failed to update template'));
}
});
},
previewEmail: function(e) {
e.preventDefault();
var body = '';
if (typeof tinymce !== 'undefined' && tinymce.get('template-body')) {
body = tinymce.get('template-body').getContent();
} else {
body = $('#template-body').val();
}
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_preview_email',
nonce: mapleCartsAdmin.nonce,
template_id: $('input[name="id"]').val(),
subject: $('input[name="subject"]').val(),
body: body
}, function(response) {
if (response.success) {
$('.maple-carts-preview-subject').text('Subject: ' + response.data.subject);
var iframe = document.getElementById('maple-carts-preview-frame');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write(response.data.body);
iframeDoc.close();
$('#maple-carts-preview-modal').show();
} else {
alert('Error: ' + (response.data || 'Failed to generate preview'));
}
});
},
openTestModal: function(e) {
e.preventDefault();
$('#maple-carts-test-modal').show();
$('.maple-carts-test-result').html('');
},
sendTestEmail: function(e) {
e.preventDefault();
var $btn = $(this);
var email = $('#test-email-address').val();
if (!email) {
alert('Please enter an email address');
return;
}
var body = '';
if (typeof tinymce !== 'undefined' && tinymce.get('template-body')) {
body = tinymce.get('template-body').getContent();
} else {
body = $('#template-body').val();
}
$btn.prop('disabled', true).text('Sending...');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_send_test_email',
nonce: mapleCartsAdmin.nonce,
email: email,
subject: $('input[name="subject"]').val(),
body: body
}, function(response) {
$btn.prop('disabled', false).text('Send Test');
if (response.success) {
$('.maple-carts-test-result').html('<p style="color:green;">' + response.data + '</p>');
} else {
$('.maple-carts-test-result').html('<p style="color:red;">' + response.data + '</p>');
}
});
},
closeModal: function() {
$('.maple-carts-modal').hide();
}
};
$(document).ready(function() {
MapleCartsAdmin.init();
// Email mode toggle.
$('input[name="email_mode"]').on('change', function() {
var mode = $(this).val();
if (mode === 'mailjet') {
$('#mailjet-settings').show();
$('#builtin-email-settings').hide();
} else {
$('#mailjet-settings').hide();
$('#builtin-email-settings').show();
}
});
// Test Mailjet connection.
$('#test-mailjet-connection').on('click', function() {
var $btn = $(this);
var $status = $('#mailjet-status');
var apiKey = $('#mailjet_api_key').val();
var secretKey = $('#mailjet_secret_key').val();
if (!apiKey || !secretKey) {
$status.html('<span style="color:red;">Please enter API credentials first.</span>');
return;
}
$btn.prop('disabled', true);
$status.html('<span>Testing connection...</span>');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_test_mailjet',
nonce: mapleCartsAdmin.nonce,
api_key: apiKey,
secret_key: secretKey
}, function(response) {
$btn.prop('disabled', false);
if (response.success) {
$status.html('<span style="color:green;">✓ ' + response.data.message + '</span>');
} else {
$status.html('<span style="color:red;">✗ ' + response.data + '</span>');
}
}).fail(function() {
$btn.prop('disabled', false);
$status.html('<span style="color:red;">✗ Connection failed</span>');
});
});
// Setup Mailjet properties.
$('#setup-mailjet-properties').on('click', function() {
var $btn = $(this);
var $status = $('#mailjet-status');
$btn.prop('disabled', true);
$status.html('<span>Setting up contact properties...</span>');
$.post(mapleCartsAdmin.ajaxUrl, {
action: 'maple_carts_setup_mailjet_properties',
nonce: mapleCartsAdmin.nonce
}, function(response) {
$btn.prop('disabled', false);
if (response.success) {
$status.html('<span style="color:green;">✓ ' + response.data.message + '</span>');
} else {
$status.html('<span style="color:red;">✗ ' + response.data + '</span>');
}
}).fail(function() {
$btn.prop('disabled', false);
$status.html('<span style="color:red;">✗ Setup failed</span>');
});
});
});
})(jQuery);

View file

@ -0,0 +1,10 @@
<?php
/**
* Silence is golden.
*
* @package MapleCarts
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}

View file

@ -0,0 +1,157 @@
/**
* Maple Carts - Frontend cart tracking.
*/
(function($) {
'use strict';
var MapleCarts = {
saveTimeout: null,
lastSavedData: '',
init: function() {
this.bindEvents();
this.showGdprNotice();
// Initial save after page load.
setTimeout(function() {
MapleCarts.saveCart();
}, 2000);
},
bindEvents: function() {
// Classic checkout fields.
$(document).on('change keyup', '#billing_email', this.debounce(this.saveCart, 500));
$(document).on('change keyup', '#billing_first_name, #billing_last_name, #billing_phone', this.debounce(this.saveCart, 1000));
$(document).on('change', '#billing_address_1, #billing_city, #billing_state, #billing_postcode, #billing_country', this.debounce(this.saveCart, 1000));
// WooCommerce Blocks checkout.
$(document).on('change keyup', '[id^="email"]', this.debounce(this.saveCart, 500));
$(document).on('change keyup', 'input[autocomplete="email"]', this.debounce(this.saveCart, 500));
// Save on blur for email field.
$(document).on('blur', '#billing_email, [id^="email"], input[autocomplete="email"]', function() {
MapleCarts.saveCart();
});
// Cart updates.
$(document.body).on('updated_cart_totals', this.saveCart);
$(document.body).on('updated_checkout', this.saveCart);
// Consent checkbox - save when checked.
$(document).on('change', '#maple_carts_consent', function() {
if ($(this).is(':checked')) {
MapleCarts.saveCart();
}
});
},
showGdprNotice: function() {
if (mapleCartsData.gdprNotice && mapleCartsData.gdprNotice.length > 0) {
var notice = $('<div class="maple-carts-gdpr-notice woocommerce-info">' + mapleCartsData.gdprNotice + '</div>');
$('.woocommerce-checkout').prepend(notice);
}
},
getFormData: function() {
var data = {
session_id: mapleCartsData.sessionId
};
// Check for consent checkbox if it exists.
var consentCheckbox = $('#maple_carts_consent');
if (consentCheckbox.length > 0 && !consentCheckbox.is(':checked')) {
// Consent required but not given - don't save.
return null;
}
data.consent = consentCheckbox.length > 0 ? (consentCheckbox.is(':checked') ? '1' : '0') : '1';
// Get email - try multiple selectors for compatibility.
var email = $('#billing_email').val() ||
$('[id^="email"]').val() ||
$('input[autocomplete="email"]').val() ||
$('input[type="email"]').first().val() || '';
data.email = email.trim().toLowerCase();
// Get billing fields.
var billingFields = [
'first_name', 'last_name', 'phone', 'address_1', 'address_2',
'city', 'state', 'postcode', 'country'
];
billingFields.forEach(function(field) {
var value = $('#billing_' + field).val();
if (value) {
data['billing_' + field] = value;
}
});
// Try Blocks checkout fields.
if (!data.billing_first_name) {
data.billing_first_name = $('input[autocomplete="given-name"]').val() || '';
}
if (!data.billing_last_name) {
data.billing_last_name = $('input[autocomplete="family-name"]').val() || '';
}
if (!data.billing_phone) {
data.billing_phone = $('input[autocomplete="tel"]').val() || '';
}
return data;
},
saveCart: function() {
var data = MapleCarts.getFormData();
// Don't save if consent not given or data is null.
if (!data) {
return;
}
// Don't save without email or session.
if (!data.email || !data.session_id) {
return;
}
// Don't save if email is invalid.
if (!MapleCarts.isValidEmail(data.email)) {
return;
}
// Don't save if data hasn't changed.
var dataHash = JSON.stringify(data);
if (dataHash === MapleCarts.lastSavedData) {
return;
}
data.action = 'maple_carts_save';
data.nonce = mapleCartsData.nonce;
$.post(mapleCartsData.ajaxUrl, data, function(response) {
if (response.success) {
MapleCarts.lastSavedData = dataHash;
}
});
},
isValidEmail: function(email) {
var re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
},
debounce: function(func, wait) {
return function() {
var context = this, args = arguments;
clearTimeout(MapleCarts.saveTimeout);
MapleCarts.saveTimeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}
};
$(document).ready(function() {
MapleCarts.init();
});
})(jQuery);