// Rozszerzona wersja z dodatkowymi opcjami
class CartAbandonmentNotifier {
constructor(options = {}) {
this.config = {
originalTitle: document.title,
alertTitles: [
'🛒 Nie zapomnij o swoich produktach!',
'⏰ Twój koszyk czeka na Ciebie!',
'💰 Dokończ zakupy teraz!'
],
blinkInterval: 2000,
titleRotationInterval: 6000,
showFavicon: true,
customMessages: true,
...options
};
this.state = {
blinkTimer: null,
rotationTimer: null,
isBlinking: false,
cartHasItems: false,
currentTitleIndex: 0,
originalFavicon: null
};
this.init();
}
// Sprawdzanie stanu koszyka z większą liczbą metod
async checkCartStatus() {
try {
// Metoda 1: PrestaShop global object
if (typeof prestashop !== 'undefined' && prestashop.cart) {
this.state.cartHasItems = prestashop.cart.products_count > 0;
return;
}
// Metoda 2: AJAX request
const response = await fetch(prestashop.urls.base_url + 'index.php?controller=cart&ajax=1&action=refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'ajax=1'
});
const data = await response.json();
if (data.cart) {
this.state.cartHasItems = data.cart.products_count > 0;
return;
}
} catch (error) {
console.warn('Błąd AJAX:', error);
}
// Metoda 3: DOM parsing jako fallback
const cartElements = [
'.cart-products-count',
'.shopping-cart .count',
'#cart-total-quantity',
'[data-cart-quantity]'
];
for (const selector of cartElements) {
const element = document.querySelector(selector);
if (element) {
const count = parseInt(element.textContent) || parseInt(element.getAttribute('data-cart-quantity')) || 0;
this.state.cartHasItems = count > 0;
return;
}
}
}
// Zmiana favicon
changeFavicon(isAlert = false) {
if (!this.config.showFavicon) return;
const favicon = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
if (!favicon) return;
if (isAlert && !this.state.originalFavicon) {
this.state.originalFavicon = favicon.href;
// Tworzenie prostej ikonki alertu (czerwona kropka)
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ff0000';
ctx.beginPath();
ctx.arc(26, 6, 6, 0, 2 * Math.PI);
ctx.fill();
favicon.href = canvas.toDataURL();
} else if (!isAlert && this.state.originalFavicon) {
favicon.href = this.state.originalFavicon;
}
}
// Rotacja komunikatów
getNextTitle() {
const title = this.config.alertTitles[this.state.currentTitleIndex];
this.state.currentTitleIndex = (this.state.currentTitleIndex + 1) % this.config.alertTitles.length;
return title;
}
// Rozpoczęcie migania z rotacją komunikatów
startBlinking() {
if (this.state.isBlinking || !this.state.cartHasItems) return;
this.state.isBlinking = true;
let showAlert = true;
let currentAlertTitle = this.getNextTitle();
this.changeFavicon(true);
// Timer migania tytułu
this.state.blinkTimer = setInterval(() => {
document.title = showAlert ? currentAlertTitle : this.config.originalTitle;
showAlert = !showAlert;
}, this.config.blinkInterval);
// Timer rotacji komunikatów
if (this.config.alertTitles.length > 1) {
this.state.rotationTimer = setInterval(() => {
currentAlertTitle = this.getNextTitle();
}, this.config.titleRotationInterval);
}
}
// Zatrzymanie wszystkich efektów
stopBlinking() {
if (this.state.blinkTimer) {
clearInterval(this.state.blinkTimer);
this.state.blinkTimer = null;
}
if (this.state.rotationTimer) {
clearInterval(this.state.rotationTimer);
this.state.rotationTimer = null;
}
this.state.isBlinking = false;
document.title = this.config.originalTitle;
this.changeFavicon(false);
}
// Obsługa zmian widoczności
async handleVisibilityChange() {
await this.checkCartStatus();
if (document.hidden && this.state.cartHasItems) {
this.startBlinking();
} else {
this.stopBlinking();
}
}
// Inicjalizacja
init() {
this.checkCartStatus();
// Page Visibility API
document.addEventListener('visibilitychange', () => this.handleVisibilityChange());
// Nasłuchiwanie zmian w koszyku PrestaShop
if (typeof prestashop !== 'undefined') {
prestashop.on('updateCart', () => {
this.checkCartStatus().then(() => {
if (!this.state.cartHasItems && this.state.isBlinking) {
this.stopBlinking();
}
});
});
}
// Obsługa przycisków dodawania do koszyka
document.addEventListener('click', (e) => {
if (e.target.closest('.add-to-cart, .remove-from-cart, [data-button-action="add-to-cart"]')) {
setTimeout(() => this.checkCartStatus(), 500);
}
});
// Czyszczenie przed zamknięciem
window.addEventListener('beforeunload', () => this.stopBlinking());
}
}
// Inicjalizacja z custom konfiguracją
document.addEventListener('DOMContentLoaded', function() {
new CartAbandonmentNotifier({
alertTitles: [
'🛒 Masz produkty w koszyku!',
'⚡ Wróć i dokończ zakupy!',
'🎯 Twoje produkty czekają na Ciebie!'
],
blinkInterval: 1500,
titleRotationInterval: 5000
});
});