fix: properly call parent init in cart and product components

Issue:
- sessionId was undefined when cart/product pages loaded
- Parent shopLayoutData init() was being overridden, not called
- Session ID setup in parent wasn't running

Solution:
- Store reference to baseData before spreading
- Explicitly call baseData.init() in child component init
- This ensures sessionId is initialized before cart/product logic runs
- Add session ID logging for debugging

Now the session ID is properly initialized and cart functionality works.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-23 09:28:15 +01:00
parent 84c6c38a50
commit 4c69a94f14
2 changed files with 86 additions and 64 deletions

View File

@@ -169,38 +169,47 @@
{% block extra_scripts %} {% block extra_scripts %}
<script> <script>
document.addEventListener('alpine:init', () => { document.addEventListener('alpine:init', () => {
Alpine.data('shoppingCart', () => ({ Alpine.data('shoppingCart', () => {
...shopLayoutData(), const baseData = shopLayoutData();
items: [], return {
loading: false, ...baseData,
updating: false,
// Computed properties items: [],
get totalItems() { loading: false,
return this.items.reduce((sum, item) => sum + item.quantity, 0); updating: false,
},
get subtotal() { // Computed properties
return this.items.reduce((sum, item) => get totalItems() {
sum + (parseFloat(item.price) * item.quantity), 0 return this.items.reduce((sum, item) => sum + item.quantity, 0);
); },
},
get shipping() { get subtotal() {
// Free shipping over €50 return this.items.reduce((sum, item) =>
return this.subtotal >= 50 ? 0 : 5.99; sum + (parseFloat(item.price) * item.quantity), 0
}, );
},
get total() { get shipping() {
return this.subtotal + this.shipping; // Free shipping over €50
}, return this.subtotal >= 50 ? 0 : 5.99;
},
// Initialize get total() {
async init() { return this.subtotal + this.shipping;
console.log('[SHOP] Cart page initializing...'); },
await this.loadCart();
}, // Initialize
async init() {
console.log('[SHOP] Cart page initializing...');
// Call parent init to set up sessionId
if (baseData.init) {
baseData.init.call(this);
}
await this.loadCart();
},
// Load cart from API // Load cart from API
async loadCart() { async loadCart() {
@@ -302,7 +311,8 @@ document.addEventListener('alpine:init', () => {
window.location.href = '{{ base_url }}shop/checkout'; window.location.href = '{{ base_url }}shop/checkout';
} }
} }
})); };
});
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@@ -216,47 +216,58 @@ window.PRODUCT_ID = {{ product_id }};
window.VENDOR_ID = {{ vendor.id }}; window.VENDOR_ID = {{ vendor.id }};
document.addEventListener('alpine:init', () => { document.addEventListener('alpine:init', () => {
Alpine.data('productDetail', () => ({ Alpine.data('productDetail', () => {
...shopLayoutData(), const baseData = shopLayoutData();
// Data return {
product: null, ...baseData,
relatedProducts: [],
loading: false,
addingToCart: false,
quantity: 1,
selectedImage: null,
vendorId: window.VENDOR_ID,
productId: window.PRODUCT_ID,
// Computed properties // Data
get canAddToCart() { product: null,
return this.product?.is_active && relatedProducts: [],
this.product?.available_inventory > 0 && loading: false,
this.quantity > 0 && addingToCart: false,
this.quantity <= this.product?.available_inventory; quantity: 1,
}, selectedImage: null,
vendorId: window.VENDOR_ID,
productId: window.PRODUCT_ID,
get totalPrice() { // Computed properties
const price = this.product?.sale_price || this.product?.price || 0; get canAddToCart() {
return price * this.quantity; return this.product?.is_active &&
}, this.product?.available_inventory > 0 &&
this.quantity > 0 &&
this.quantity <= this.product?.available_inventory;
},
get hasAdditionalDetails() { get totalPrice() {
return this.product?.marketplace_product?.gtin || const price = this.product?.sale_price || this.product?.price || 0;
this.product?.condition || return price * this.quantity;
this.product?.marketplace_product?.color || },
this.product?.marketplace_product?.size ||
this.product?.marketplace_product?.material;
},
// Initialize get hasAdditionalDetails() {
async init() { return this.product?.marketplace_product?.gtin ||
console.log('[SHOP] Product detail page initializing...'); this.product?.condition ||
console.log('[SHOP] Product ID:', this.productId); this.product?.marketplace_product?.color ||
console.log('[SHOP] Vendor ID:', this.vendorId); this.product?.marketplace_product?.size ||
await this.loadProduct(); this.product?.marketplace_product?.material;
}, },
// Initialize
async init() {
console.log('[SHOP] Product detail page initializing...');
// Call parent init to set up sessionId
if (baseData.init) {
baseData.init.call(this);
}
console.log('[SHOP] Product ID:', this.productId);
console.log('[SHOP] Vendor ID:', this.vendorId);
console.log('[SHOP] Session ID:', this.sessionId);
await this.loadProduct();
},
// Load product details // Load product details
async loadProduct() { async loadProduct() {
@@ -384,7 +395,8 @@ document.addEventListener('alpine:init', () => {
this.addingToCart = false; this.addingToCart = false;
} }
} }
})); };
});
}); });
</script> </script>
{% endblock %} {% endblock %}