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>
This commit is contained in:
2025-11-23 09:39:27 +01:00
parent 3d585e563f
commit f217defd60
2 changed files with 539 additions and 3 deletions

View File

@@ -31,13 +31,25 @@ DATABASE_URL=sqlite:///./ecommerce.db
make migrate-up
```
### 4. Verify Setup
### 4. Seed Test Data (Optional)
```bash
# Create test vendors, products, and inventory
python scripts/create_test_data.py
# Create inventory entries for existing products
python scripts/create_inventory.py
# Create landing pages for vendors
python scripts/create_landing_page.py
```
### 5. Verify Setup
```bash
# Check that everything is working
make verify-setup
```
### 5. Start Development
### 6. Start Development
```bash
# Start the development server
make dev
@@ -185,8 +197,139 @@ make migrate-status
4. **Include meaningful messages when creating migrations**
5. **Review generated migrations before applying them**
## Data Seeding for Development
### Overview
After setting up your database schema with migrations, you'll need test data to develop and test features. We provide several scripts to populate your database with sample data.
### Available Seeding Scripts
#### 1. Create Test Data
**Script:** `scripts/create_test_data.py`
Creates complete test data including vendors, marketplace products, vendor products, themes, and content pages.
```bash
python scripts/create_test_data.py
```
**What it creates:**
- 3 test vendors (WizaMart, Fashion Hub, The Book Store)
- 20 marketplace products per vendor
- Vendor-specific products with pricing
- Vendor themes with custom colors
- Sample CMS content pages (About, Contact, FAQ, etc.)
#### 2. Create Inventory Entries
**Script:** `scripts/create_inventory.py`
Creates inventory entries for products that don't have inventory. This is **required** for the shop to function properly, as products with 0 inventory cannot be added to cart.
```bash
python scripts/create_inventory.py
```
**What it does:**
- Finds all products without inventory entries
- Creates inventory record for each product
- Sets 100 units available in "Main Warehouse"
- Can be run multiple times (only creates missing entries)
**Why it's needed:**
- Product `available_inventory` is calculated from inventory entries
- Empty inventory table = 0 inventory for all products
- Add to cart functionality requires `available_inventory > 0`
#### 3. Create Landing Pages
**Script:** `scripts/create_landing_page.py`
Creates or updates landing pages for vendors with different templates.
```bash
# Interactive mode
python scripts/create_landing_page.py
# Or programmatically in Python
from scripts.create_landing_page import create_landing_page
create_landing_page('wizamart', template='modern')
```
**Available templates:**
- `default` - Clean professional layout with 3-column quick links
- `minimal` - Ultra-simple centered design with single CTA
- `modern` - Full-screen hero with animations and features
- `full` - Maximum features with split-screen hero and stats
### Complete Setup Workflow
For a fresh development environment with test data:
```bash
# 1. Setup database schema
make migrate-up
# 2. Create test vendors and products
python scripts/create_test_data.py
# 3. Create inventory (REQUIRED for shop to work)
python scripts/create_inventory.py
# 4. Create landing pages
python scripts/create_landing_page.py
# Follow interactive prompts to create landing pages
# 5. Start the server
make dev
# 6. Test the shop
# Visit: http://localhost:8000/vendors/wizamart/shop/
```
### Common Issues
**Problem: Products can't be added to cart**
```bash
# Solution: Create inventory entries
python scripts/create_inventory.py
```
**Problem: Landing page shows 404**
```bash
# Solution: Create landing page for the vendor
python scripts/create_landing_page.py
# OR the vendor will auto-redirect to /shop/
```
**Problem: No products showing in shop**
```bash
# Solution: Create test data
python scripts/create_test_data.py
```
### Database Reset (Development Only)
To start completely fresh:
```bash
# 1. Backup first (optional but recommended)
cp wizamart.db wizamart.db.backup
# 2. Delete database
rm wizamart.db
# 3. Recreate schema
make migrate-up
# 4. Seed all data
python scripts/create_test_data.py
python scripts/create_inventory.py
python scripts/create_landing_page.py
```
## Next Steps
- [Database Setup Guide](DATABASE_SETUP_GUIDE.md) - Complete database setup guide
- [Shop Setup Guide](../guides/shop-setup.md) - Configure vendor storefronts
- [Landing Pages Guide](../features/vendor-landing-pages.md) - Customize landing pages
- [Database Migrations Guide](../development/database-migrations.md) - Advanced migration workflows
- [API Documentation](../api/index.md) - Start building features

View File

@@ -0,0 +1,393 @@
# 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:**
```bash
# 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:**
```python
# 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:
```javascript
// 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:
```jinja2
{# 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:
```html
<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):**
```python
# 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:**
```python
# 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.
### Missing `/shop/` in Links
**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:**
```jinja2
{# 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:**
```python
# Root handler checks for landing page
if has_landing_page():
return render_landing_page()
else:
return redirect("/shop/") # Fallback
```
**Solution:**
```bash
# 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:**
```jinja2
{# 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:**
```javascript
// 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:
```html
{% 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
```javascript
// 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
```javascript
// In browser console
localStorage.getItem('cart_session_id')
// Should show: "session_1763765104510_zc866tt5d"
```
### Inspect Product Data
```javascript
// 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