diff --git a/assets/src/js/front/tutor-cart-button.js b/assets/src/js/front/tutor-cart-button.js new file mode 100644 index 0000000000..92d6f668c4 --- /dev/null +++ b/assets/src/js/front/tutor-cart-button.js @@ -0,0 +1,44 @@ +/** + * Tutor Cart Button - Global JavaScript for cart count updates + * + * This file handles dynamic cart count updates for the Tutor LMS cart button. + * It listens for custom events dispatched by the cart operations and updates + * the cart count display across all cart button instances on the page. + * + * @package Tutor + * @since 4.1.0 + */ + +document.addEventListener('DOMContentLoaded', function () { + // Listen for add to cart event + document.addEventListener('tutorAddToCartEvent', function (event) { + const cartCounters = document.querySelectorAll('.tutor-cart-count'); + cartCounters.forEach(function (counter) { + if (event.detail.cart_count > 0) { + counter.textContent = event.detail.cart_count; + counter.style.display = 'inline-block'; + } + }); + }); + + // Listen for remove from cart event + document.addEventListener('tutorRemoveCartEvent', function (event) { + const cartCounters = document.querySelectorAll('.tutor-cart-count'); + cartCounters.forEach(function (counter) { + const mode = counter.getAttribute('data-show-count') || 'if_has_items'; + + if (event.detail.cart_count > 0) { + counter.textContent = event.detail.cart_count; + counter.style.display = 'inline-block'; + } else { + if (mode === 'always') { + counter.textContent = '0'; + counter.style.display = 'inline-block'; + } else { + counter.textContent = ''; + counter.style.display = 'none'; + } + } + }); + }); +}); diff --git a/assets/src/js/front/tutor-front.js b/assets/src/js/front/tutor-front.js index ac1229e3d5..b47995c7ae 100644 --- a/assets/src/js/front/tutor-front.js +++ b/assets/src/js/front/tutor-front.js @@ -8,6 +8,7 @@ import './pages/cart'; import './pages/checkout'; import './pages/course-landing'; import './pages/instructor-list-filter'; +import './tutor-cart-button'; /** * Codes from this file should be decentralized according to relavent file/folder structure. diff --git a/assets/src/js/gutenberg/cart-button/block.json b/assets/src/js/gutenberg/cart-button/block.json new file mode 100644 index 0000000000..16778b3a18 --- /dev/null +++ b/assets/src/js/gutenberg/cart-button/block.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "tutor-gutenberg/cart-button", + "title": "Tutor Cart Button", + "category": "tutor", + "icon": "cart", + "description": "Display a cart button with item count for Tutor LMS ecommerce", + "attributes": { + "showCount": { + "type": "string", + "default": "if_has_items" + }, + "customClass": { + "type": "string", + "default": "cart-contents" + }, + "iconColor": { + "type": "string", + "default": "" + }, + "badgeBgColor": { + "type": "string", + "default": "#e74c3c" + }, + "badgeTextColor": { + "type": "string", + "default": "#ffffff" + } + }, + "supports": { + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "tutor-gutenberg-cart-button", + "style": "tutor-cart-button", + "render": "file:./render.php" +} diff --git a/assets/src/js/gutenberg/cart-button/edit.js b/assets/src/js/gutenberg/cart-button/edit.js new file mode 100644 index 0000000000..4cb09f77e7 --- /dev/null +++ b/assets/src/js/gutenberg/cart-button/edit.js @@ -0,0 +1,112 @@ +import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; +import { PanelBody, RadioControl, TextControl, BaseControl } from '@wordpress/components'; +import { ColorPalette } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +export default function Edit( { attributes, setAttributes } ) { + const { showCount, customClass, iconColor, badgeBgColor, badgeTextColor } = attributes; + + // Use a sample count for editor preview + const cartCount = 3; + + return ( + <> + + + setAttributes( { showCount: value } ) } + help={ __( 'The editor does not display the real count value, but a placeholder to indicate how it will look on the front-end.', 'tutor' ) } + /> + setAttributes( { customClass: value } ) } + placeholder="cart-contents" + /> + + + + + + + setAttributes( { iconColor: value } ) } + disableCustomColors={ false } + clearable={ true } + /> + + + setAttributes( { badgeBgColor: value } ) } + disableCustomColors={ false } + clearable={ true } + /> + + + + +
+
+ + + + + + + { ( showCount === 'always' || showCount === 'if_has_items' ) && ( + + { cartCount } + + ) } + +
+
+ + ); +} diff --git a/assets/src/js/gutenberg/cart-button/index.js b/assets/src/js/gutenberg/cart-button/index.js new file mode 100644 index 0000000000..b156efcd9f --- /dev/null +++ b/assets/src/js/gutenberg/cart-button/index.js @@ -0,0 +1,10 @@ +import { registerBlockType } from '@wordpress/blocks'; +import metadata from './block.json'; +import Edit from './edit'; +import save from './save'; + +registerBlockType( metadata.name, { + ...metadata, + edit: Edit, + save, +} ); diff --git a/assets/src/js/gutenberg/cart-button/render.php b/assets/src/js/gutenberg/cart-button/render.php new file mode 100644 index 0000000000..f1df34815d --- /dev/null +++ b/assets/src/js/gutenberg/cart-button/render.php @@ -0,0 +1,48 @@ + 'true', + 'show_count' => isset( $attributes['showCount'] ) ? $attributes['showCount'] : 'if_has_items', + 'class' => isset( $attributes['customClass'] ) && ! empty( $attributes['customClass'] ) ? $attributes['customClass'] : 'cart-contents', +); + +$shortcode = '[tutor_cart_button'; +foreach ( $atts as $key => $value ) { + $shortcode .= ' ' . $key . '="' . esc_attr( $value ) . '"'; +} +$shortcode .= ']'; + +// Build inline CSS variables for custom colors set in the block editor. +// The stylesheet consumes these via var(--tutor-cart-*) with hardcoded fallbacks, +// so no