403Webshell
Server IP : 104.171.130.249  /  Your IP : 216.73.216.146
Web Server : nginx/1.25.5
System : Linux 0dac65491b7e 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64
User : root ( 0)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/html/wp-content/themes/matreshka/assets/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/wp-content/themes/matreshka/assets/js/cart.js
jQuery(document).ready(function($) {
    'use strict';

    // Function to update minus button icon based on quantity
    function updateMinusIcon($wrapper) {
        var $input = $wrapper.find('.qty-input');
        var $minusBtn = $wrapper.find('.qty-minus');
        var currentVal = parseFloat($input.val()) || 0;
        var min = parseFloat($input.attr('min')) || 0;
        var iconSrc = $minusBtn.find('img').attr('src');
        
        if (!iconSrc) return;
        
        if (currentVal <= 1) {
            // Show trash icon when quantity is 1 or less
            if (iconSrc.indexOf('minus.svg') !== -1) {
                $minusBtn.find('img').attr('src', iconSrc.replace('minus.svg', 'Trash.svg'));
                $minusBtn.find('img').attr('alt', 'delete icon');
            }
        } else {
            // Show minus icon when quantity is more than 1
            if (iconSrc.indexOf('Trash.svg') !== -1) {
                $minusBtn.find('img').attr('src', iconSrc.replace('Trash.svg', 'minus.svg'));
                $minusBtn.find('img').attr('alt', 'subtract icon');
            }
        }
    }

    function getQuantityInputsByName(inputName) {
        return $('.woocommerce-cart-form input[name]').filter(function() {
            return this.name === inputName;
        });
    }

    function syncQuantityInputs($sourceInput) {
        var inputName = $sourceInput.attr('name');

        if (!inputName) {
            return $sourceInput;
        }

        var value = $sourceInput.val();
        var $inputs = getQuantityInputsByName(inputName);

        $inputs.each(function() {
            var $input = $(this);
            var $wrapper = $input.closest('.quantity-cart-group');

            $input.val(value);

            if ($wrapper.length) {
                $wrapper.find('.qty-display').text(value + ' шт');
                updateMinusIcon($wrapper);
            }
        });

        return $inputs;
    }

    // Update all icons on page load
    function updateAllIcons() {
        $('.quantity-cart-group').each(function() {
            updateMinusIcon($(this));
        });
    }

    // Allow clicking on quantity display to edit directly
    $(document).on('click', '.quantity-cart-group .qty-display', function(e) {
        e.preventDefault();
        var $display = $(this);
        var $wrapper = $display.closest('.quantity-cart-group');
        var $input = $wrapper.find('.qty-input');
        
        // Hide display, show input
        $display.addClass('hidden');
        $input.addClass('active').focus().select();
    });

    // Handle input blur (when user clicks away)
    $(document).on('blur', '.quantity-cart-group .qty-input', function() {
        var $input = $(this);
        var $wrapper = $input.closest('.quantity-cart-group');
        var $display = $wrapper.find('.qty-display');
        var newVal = parseFloat($input.val()) || 0;
        var min = parseFloat($input.attr('min')) || 0;
        var max = parseFloat($input.attr('max'));
        
        // Validate value
        if (newVal < min) newVal = min;
        if (max && newVal > max) newVal = max;
        
        $input.val(newVal);
        syncQuantityInputs($input);
        $display.text(newVal + ' шт');
        
        // Show display, hide input
        $input.removeClass('active');
        $display.removeClass('hidden');
        
        // Update icon
        updateMinusIcon($wrapper);
        
        // Trigger change event to update cart
        $input.trigger('change');
    });

    // Handle Enter key on input
    $(document).on('keypress', '.quantity-cart-group .qty-input', function(e) {
        if (e.which === 13) {
            e.preventDefault();
            $(this).blur();
        }
    });

    // Cart quantity controls
    $(document).on('click', '.quantity-cart-group .qty-minus, .quantity-cart-group .qty-plus', function(e) {
        e.preventDefault();
        
        var $button = $(this);
        var $wrapper = $button.closest('.quantity-cart-group');
        var $input = $wrapper.find('.qty-input');
        var $display = $wrapper.find('.qty-display');
        var currentVal = parseFloat($input.val()) || 0;
        var min = parseFloat($input.attr('min')) || 0;
        var max = parseFloat($input.attr('max'));
        var step = parseFloat($input.attr('step')) || 1;
        
        var newVal = currentVal;
        
        if ($button.hasClass('qty-plus')) {
            // Increase quantity
            if (max && currentVal >= max) {
                newVal = max;
            } else {
                newVal = currentVal + step;
            }
        } else if ($button.hasClass('qty-minus')) {
            // Decrease quantity
            if (currentVal <= 1) {
                // Remove item when quantity is 1 and minus is clicked
                newVal = 0;
            } else {
                newVal = Math.max(min, currentVal - step);
            }
        }
        
        // Update input value
        $input.val(newVal);
        syncQuantityInputs($input);
        
        // Update display text
        if (newVal > 0) {
            $display.text(newVal + ' шт');
        }
        
        // Update icon immediately
        updateMinusIcon($wrapper);
        
        // Trigger input change to update cart
        $input.trigger('change');
    });

    // Auto-update cart on quantity change
    var updateTimeout;
    $(document).on('change', '.quantity-cart-group .qty-input, .quantity .qty-input', function() {
        var $thisInput = $(this);
        var $wrapper = $thisInput.closest('.quantity-cart-group');
        syncQuantityInputs($thisInput);
        
        if (updateTimeout !== undefined) {
            clearTimeout(updateTimeout);
        }
        
        updateTimeout = setTimeout(function() {
            // Update icon before submitting
            if ($wrapper.length) {
                updateMinusIcon($wrapper);
            }
            
            // Find and trigger update cart button
            var $updateButton = $('button[name="update_cart"]');
            if ($updateButton.length) {
                $updateButton.prop('disabled', false).trigger('click');
            } else {
                // If no update button, submit the form
                $thisInput.closest('form').submit();
            }
        }, 300);
    });

    $(document).on('submit', '.woocommerce-cart-form', function() {
        var $activeInput = $(document.activeElement);

        if ($activeInput.is('.quantity-cart-group .qty-input')) {
            syncQuantityInputs($activeInput);
        }
    });

    // Update icons after cart updates via AJAX
    $(document.body).on('updated_cart_totals updated_wc_div', function() {
        setTimeout(function() {
            updateAllIcons();
            
            // Update cart badge in header
            if (typeof matreshka_ajax !== 'undefined') {
                $.ajax({
                    url: matreshka_ajax.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'matreshka_get_cart_count',
                        nonce: matreshka_ajax.nonce
                    },
                    success: function(response) {
                        if (response.success && response.data.cart_count !== undefined) {
                            var cartCount = response.data.cart_count;
                            var $cartBadge = $('.cart-count-badge');
                            
                            if (cartCount > 0) {
                                if ($cartBadge.length) {
                                    $cartBadge.text(cartCount);
                                } else {
                                    var $badge = $('<span>')
                                        .addClass('cart-count-badge montserrat-semibold')
                                        .text(cartCount);
                                    $('.cart-icon-wrapper').append($badge);
                                }
                            } else {
                                $cartBadge.remove();
                            }
                        }
                    }
                });
            }
        }, 100);
    });

    // Clear cart functionality
    $(document).on('click', '.btn-link', function(e) {
        var linkText = $(this).text().trim();
        if (linkText === 'Очистити' || linkText === 'Очистить') {
            if (!confirm('Ви впевнені, що хочете очистити кошик?')) {
                e.preventDefault();
                return false;
            }
        }
    });

    // Handle product removal from cart
    $(document).on('click', 'a.remove', function() {
        // Trigger badge update after removal
        setTimeout(function() {
            $(document.body).trigger('updated_wc_div');
        }, 500);
    });

    function updateCouponSubmit($input) {
        var $form = $input.closest('form');
        var $button = $form.find('button[name="apply_coupon"]');
        var hasValue = $.trim($input.val()).length > 0;

        $button.prop('hidden', !hasValue).toggleClass('is-visible', hasValue);
    }

    $('.btn-promo input[name="coupon_code"]').each(function() {
        updateCouponSubmit($(this));
    });

    $(document).on('input', '.btn-promo input[name="coupon_code"]', function() {
        updateCouponSubmit($(this));
    });

    $(document).on('click', '.cart-info .woocommerce-remove-coupon', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();

        var $link = $(this);
        var coupon = $link.data('coupon');
        var fallbackUrl = $link.attr('href');

        if (!coupon || typeof wc_cart_params === 'undefined') {
            window.location.href = fallbackUrl;
            return;
        }

        $link.addClass('disabled').attr('aria-disabled', 'true');

        $.ajax({
            type: 'POST',
            url: wc_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'remove_coupon'),
            data: {
                security: wc_cart_params.remove_coupon_nonce,
                coupon: coupon
            },
            complete: function() {
                window.location.reload();
            },
            error: function() {
                window.location.href = fallbackUrl;
            }
        });
    });

    // Apply coupon on Enter key
    $(document).on('keypress', '.btn-promo input[name="coupon_code"]', function(e) {
        if (e.which === 13) {
            e.preventDefault();
            $(this).closest('form').find('button[name="apply_coupon"]').trigger('click');
        }
    });

    // Show or hide the detailed savings rows in the cart summary.
    $(document).on('click', '#btn-toggle-sale-details', function() {
        var $group = $('#sale-group');
        var isExpanded = $group.hasClass('is-collapsed');
        $group.toggleClass('is-collapsed', !isExpanded);
        $(this).attr('aria-expanded', isExpanded ? 'true' : 'false');
    });

    // Bonus redemption. The server validates the balance and the 50% cap again.
    function updateBonusRemaining() {
        var $input = $('#bonus-redeem-points');
        var $remaining = $('#bonus-points-remaining');
        var $discount = $('#bonus-redemption-discount');
        if (!$input.length || !$remaining.length || !$discount.length) return;

        var requested = parseInt($input.val(), 10) || 0;
        var max = parseInt($input.attr('max'), 10) || 0;
        var balance = parseInt($remaining.data('balance'), 10) || 0;
        var bonusValue = parseFloat($discount.data('bonus-value')) || 0.1;
        requested = Math.max(0, Math.min(requested, max));
        $remaining.text(Math.max(0, balance - requested));
        var amount = requested * bonusValue;
        var rubles = Math.floor(Math.abs(amount));
        var kopecks = Math.round((Math.abs(amount) - rubles) * 100);
        if (kopecks === 100) {
            rubles += 1;
            kopecks = 0;
        }
        $discount.html((amount < 0 ? '-' : '') + rubles.toLocaleString('ru-RU') + '<span class="price-small">' + String(kopecks).padStart(2, '0') + '</span>₽');
    }

    $(document).on('click', '#btn-toggle-bonus-redemption', function() {
        var $block = $('#matreshka-bonus-redemption');
        var isOpen = !$block.hasClass('is-open');
        $block.toggleClass('is-open', isOpen);
        $(this).attr('aria-expanded', isOpen ? 'true' : 'false');
    });

    $(document).on('input change', '#bonus-redeem-points', updateBonusRemaining);

    $(document).on('click', '#btn-use-all-bonuses', function() {
        var $input = $('#bonus-redeem-points');
        $input.val($input.attr('max')).trigger('change');
    });

    $(document).on('click', '#btn-apply-bonus-redemption', function() {
        var $button = $(this);
        var $input = $('#bonus-redeem-points');
        var points = parseInt($input.val(), 10) || 0;
        var max = parseInt($input.attr('max'), 10) || 0;
        var $message = $('#bonus-redemption-message');

        if (points < 1) {
            $message.text('Введите количество бонусов для списания.');
            return;
        }

        points = Math.min(points, max);
        $input.val(points);
        $button.prop('disabled', true);
        $message.text('Применяем бонусы…');

        $.post(matreshka_cashback.ajax_url, {
            action: 'matreshka_apply_cashback',
            nonce: matreshka_cashback.nonce,
            bonus_points: points
        }).done(function(response) {
            if (response.success) {
                window.location.reload();
                return;
            }
            $message.text(response.data && response.data.message ? response.data.message : 'Не удалось применить бонусы.');
        }).fail(function() {
            $message.text('Не удалось применить бонусы. Попробуйте ещё раз.');
        }).always(function() {
            $button.prop('disabled', false);
        });
    });

    $(document).on('click', '#btn-remove-bonus-redemption', function() {
        var $button = $(this);
        var $message = $('#bonus-redemption-message');
        $button.prop('disabled', true);
        $message.text('Отменяем списание…');

        $.post(matreshka_cashback.ajax_url, {
            action: 'matreshka_remove_cashback',
            nonce: matreshka_cashback.nonce
        }).done(function(response) {
            if (response.success) {
                window.location.reload();
                return;
            }
            $message.text(response.data && response.data.message ? response.data.message : 'Не удалось отменить списание.');
        }).fail(function() {
            $message.text('Не удалось отменить списание. Попробуйте ещё раз.');
        }).always(function() {
            $button.prop('disabled', false);
        });
    });

    // Initialize icons and display on page load
    updateAllIcons();
    
    // Update quantity display text on page load
    $('.quantity-cart-group').each(function() {
        var $wrapper = $(this);
        var $input = $wrapper.find('.qty-input');
        var $display = $wrapper.find('.qty-display');
        var currentVal = parseFloat($input.val());
        
        if (!isNaN(currentVal) && currentVal > 0) {
            $display.text(currentVal + ' шт');
        }
    });

    // Hide "Cart updated" message
    $(document.body).on('updated_cart_totals updated_wc_div', function() {
        // Remove cart updated messages
        $('.woocommerce-message[role="alert"]').each(function() {
            if ($(this).text().indexOf('обновлена') !== -1 || 
                $(this).text().indexOf('updated') !== -1 ||
                $(this).text().indexOf('обновлено') !== -1) {
                $(this).remove();
            }
        });
    });

    // Also hide on page load
    $('.woocommerce-message[role="alert"]').each(function() {
        if ($(this).text().indexOf('обновлена') !== -1 || 
            $(this).text().indexOf('updated') !== -1 ||
            $(this).text().indexOf('обновлено') !== -1) {
            $(this).remove();
        }
    });
});

Youez - 2016 - github.com/yon3zu
LinuXploit