Files
orion/docs/troubleshooting/shop-frontend.md
Samir Boulahtit f217defd60 docs: comprehensive updates for today's shop frontend improvements
Updated documentation to cover all work completed today:

## Database Setup (docs/getting-started/database-setup.md)
- Added data seeding section with all three scripts
- Documented inventory creation requirement
- Added complete setup workflow
- Included common issues and solutions
- Added database reset instructions

## New Troubleshooting Guide (docs/troubleshooting/shop-frontend.md)
Comprehensive troubleshooting for:

### Cart and Product Issues
- Products cannot be added to cart (inventory = 0)
- Cart is empty after adding products (session ID issue)
- Root causes and solutions with code examples

### Styling and Layout Issues
- Pages with no styling (not extending base template)
- Images not loading (placeholder SVG implementation)
- Detailed before/after examples

### Navigation and Routing Issues
- Product detail 404 (duplicate /shop prefix)
- Missing /shop/ in links
- Breadcrumb navigation patterns

### Landing Page Issues
- Vendor root 404 (no landing page)
- Breadcrumb home link configuration
- Auto-redirect behavior

### Alpine.js Issues
- Component data not available (parent init not called)
- Product ID undefined (window globals solution)
- Debugging tips and console commands

All issues encountered today are now documented with:
- Clear symptoms
- Root cause explanation
- How the system works
- Step-by-step solutions
- Code examples
- Verification steps

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 09:39:27 +01:00

9.7 KiB

Shop Frontend Troubleshooting

Common issues and solutions for the vendor shop frontend.

Cart and Product Issues

Products Cannot Be Added to Cart

Symptoms:

  • "Add to Cart" button is disabled
  • No response when clicking "Add to Cart"
  • Console shows canAddToCart: false

Root Cause: Products have available_inventory: 0 because the inventory table is empty.

How it Works:

  • Product's available_inventory is a calculated property
  • It sums quantity - reserved_quantity from all inventory_entries
  • If there are no inventory entries, available_inventory = 0
  • The canAddToCart check fails when available_inventory <= 0

Solution:

# Create inventory entries for all products
python scripts/create_inventory.py

This script:

  • Finds all products without inventory entries
  • Creates inventory with 100 units in "Main Warehouse"
  • Can be run multiple times (only creates missing entries)

Verify Fix:

# Check a product's inventory
from app.core.database import SessionLocal
from models.database.product import Product

db = SessionLocal()
product = db.query(Product).first()
print(f"Available inventory: {product.available_inventory}")
# Should show: Available inventory: 100

Cart is Empty After Adding Products

Symptoms:

  • Success toast appears: "1 item(s) added to cart!"
  • Cart count in header doesn't update
  • Cart page shows 0 items
  • Console shows session_1234_abc but API returns empty cart

Root Cause: Session ID not properly initialized in Alpine.js components.

How it Works:

  • Cart uses session ID stored in localStorage as cart_session_id
  • shopLayoutData() base component initializes sessionId in its init() method
  • Child components (product, cart) must call parent init() to get sessionId
  • If parent init isn't called, sessionId is undefined

Solution Already Implemented: The product and cart pages now properly call parent init:

// In product.html and cart.html
async init() {
    // Call parent init to set up sessionId
    if (baseData.init) {
        baseData.init.call(this);
    }
    // Now sessionId is available
    await this.loadCart();
}

Verify Fix: Open browser console and check for:

🔍 [SHOP] Session ID: session_1763765104510_zc866tt5d

If you see undefined, the parent init isn't being called properly.

Styling and Layout Issues

Page Has No Styling / CSS 404 Errors

Symptoms:

  • Page displays with no styling
  • Console shows 404 errors:
    • /static/css/shared/base.css not found
    • /static/css/vendor/vendor.css not found
  • Page is just plain HTML

Root Cause: Template doesn't extend shop/base.html and has hardcoded non-existent CSS references.

How it Works:

  • All shop pages should extend shop/base.html
  • Base template includes Tailwind CSS and shop styles
  • Standalone HTML pages with <link> tags won't work

Solution: Refactor template to extend base:

{# BEFORE: Standalone HTML #}
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/static/css/shared/base.css">  ❌
</head>
<body>
    <!-- content -->
</body>
</html>

{# AFTER: Extends base #}
{% extends "shop/base.html" %}

{% block title %}My Page{% endblock %}

{% block alpine_data %}myComponent(){% endblock %}

{% block content %}
    <!-- content -->
{% endblock %}

Templates Already Fixed:

  • shop/product.html - Refactored to extend base
  • shop/cart.html - Refactored to extend base
  • shop/products.html - Already extends base
  • shop/home.html - Already extends base

Images Not Loading / Placeholder Not Showing

Symptoms:

  • Product images show broken image icon
  • Console shows 404: /static/shop/img/placeholder.jpg
  • OR images point to fake URLs like https://wizamart.example.com/images/product-1.jpg

Root Cause:

  1. Test data has fake image URLs
  2. Placeholder file was .jpg but contained SVG content

How it Works:

  • Products have marketplace_product.image_link URLs
  • Template uses fallback: :src="image || '/static/shop/img/placeholder.svg'"
  • @error handler switches to placeholder when image fails to load
  • Browsers won't render SVG content from .jpg files

Solution Already Implemented:

  • Created proper /static/shop/img/placeholder.svg
  • Added @error handlers to all image tags:
<img
    :src="product.image_link || '/static/shop/img/placeholder.svg'"
    @error="$el.src = '/static/shop/img/placeholder.svg'"
    alt="Product image"
>

Update Test Data (Optional):

# Replace fake URLs with real placeholder images
import sqlite3
conn = sqlite3.connect('wizamart.db')
cursor = conn.cursor()

cursor.execute("""
    UPDATE marketplace_products
    SET image_link = NULL
    WHERE image_link LIKE '%example.com%'
""")
conn.commit()

Navigation and Routing Issues

Product Detail Page Returns 404

Symptoms:

  • Clicking product shows 404 error
  • URL is: /vendors/wizamart/shop/shop/products/4 (double /shop/)
  • Server log shows route not found

Root Cause: Duplicate /shop prefix in route definitions when router already has prefix.

How it Works:

# Router is mounted with prefix
app.include_router(shop_pages.router, prefix="/shop")

# Route decorator should NOT repeat the prefix
@router.get("/products/{id}")  # ✅ Correct
@router.get("/shop/products/{id}")  # ❌ Wrong - creates /shop/shop/products/{id}

Solution Already Implemented: All routes in shop_pages.py have been fixed to remove duplicate /shop/ prefix.

Symptoms:

  • Links go to /vendors/wizamart/products instead of /vendors/wizamart/shop/products
  • 404 errors on navigation
  • Footer/header links broken

Root Cause: Template links missing /shop/ prefix after {{ base_url }}.

Solution:

{# WRONG #}
<a href="{{ base_url }}products">Products</a>

{# CORRECT #}
<a href="{{ base_url }}shop/products">Products</a>

All Templates Fixed:

  • shop/base.html - Header, footer, navigation
  • shop/products.html - Product links
  • shop/product.html - Breadcrumbs, related products
  • shop/cart.html - Continue shopping, checkout
  • shop/errors/404.html - All fallback links

Landing Page Issues

Vendor Root Shows 404

Symptoms:

  • http://localhost:8000/vendors/wizamart/ returns 404
  • / path not found

Root Cause: No landing page created for vendor.

How it Works:

# Root handler checks for landing page
if has_landing_page():
    return render_landing_page()
else:
    return redirect("/shop/")  # Fallback

Solution:

# Create landing page
python scripts/create_landing_page.py
# Choose vendor and template

Or Accept Redirect: The system auto-redirects to /shop/ if no landing page exists. This is normal behavior.

Breadcrumb "Home" Points to Wrong Place

Symptoms:

  • Clicking "Home" in breadcrumb goes to shop instead of landing page
  • Want "Home" to point to vendor root (/)

Solution Already Implemented:

{# Breadcrumb Home link points to vendor root #}
<a href="{{ base_url }}">Home</a>

{# Shop homepage link #}
<a href="{{ base_url }}shop/">Shop</a>

Navigation pattern:

  • Logo click/shop/ (stays in shop for convenience)
  • Breadcrumb "Home"/ (returns to landing page/root)
  • Header "Home" link/ (returns to landing page/root)

Alpine.js / JavaScript Issues

Component Data Not Available

Symptoms:

  • this.sessionId is undefined
  • this.cartCount doesn't work
  • Console: "Cannot read property of undefined"

Root Cause: Child component doesn't call parent init() method.

Solution:

// Store reference to parent
const baseData = shopLayoutData();

return {
    ...baseData,

    // Child properties
    items: [],

    // Call parent init
    async init() {
        if (baseData.init) {
            baseData.init.call(this);
        }
        // Now parent properties are initialized
        await this.loadData();
    }
};

Product ID is Undefined

Symptoms:

  • API call: /api/v1/shop/products/undefined
  • Console: productId: undefined

Root Cause: Product ID not accessible from this.$el.dataset when x-data is on <html> tag.

Solution Already Implemented: Pass via window globals:

{% block extra_scripts %}
<script>
window.PRODUCT_ID = {{ product_id }};
window.VENDOR_ID = {{ vendor.id }};

Alpine.data('productDetail', () => ({
    productId: window.PRODUCT_ID,
    vendorId: window.VENDOR_ID,
    // ...
}));
</script>
{% endblock %}

Debugging Tips

Enable Verbose Logging

// In shop-layout.js, the shopLog is already configured
// Check browser console for:
🛒 [SHOP] Shop layout initializing...
🔍 [SHOP] Session ID: session_xxx
[SHOP] Adding to cart: {...}
[SHOP] Cart loaded: 3 items

Check Session ID

// In browser console
localStorage.getItem('cart_session_id')
// Should show: "session_1763765104510_zc866tt5d"

Inspect Product Data

// In browser console on product page
Alpine.$data(document.querySelector('[x-data]')).product
// Shows full product object with inventory

Check API Responses

In browser Network tab, filter by "shop" and check:

  • GET /api/v1/shop/products - Should return products array
  • GET /api/v1/shop/cart/{session_id} - Should return cart items
  • POST /api/v1/shop/cart/{session_id}/items - Should return success

Getting Help

  1. Check this guide first
  2. Check browser console for errors
  3. Check server logs for API errors
  4. Verify database has inventory entries
  5. Ensure all templates extend shop/base.html
  6. Check that session ID is initialized

If still stuck, provide:

  • Browser console output
  • Server log excerpt
  • Network tab showing failed requests
  • Steps to reproduce