fix: implement correct base_url routing for shop frontend
Fix shop frontend links to work correctly across all three access methods:
- Custom domain (wizamart.shop)
- Subdomain (wizamart.localhost)
- Path-based (/vendor/wizamart/)
Changes:
- Update get_shop_context() to calculate base_url based on access method
- Update all shop templates to use {{ base_url }} for links
- Add base_url to shop-layout.js Alpine.js component
- Document multi-access routing in shop architecture docs
This ensures links work correctly regardless of how the shop is accessed,
solving broken navigation issues with path-based access.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,153 @@
|
||||
<DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Shop homepage</title>
|
||||
</head>
|
||||
<body>
|
||||
<-- Shop homepage -->
|
||||
</body>
|
||||
</html>
|
||||
{# app/templates/shop/home.html #}
|
||||
{% extends "shop/base.html" %}
|
||||
|
||||
{% block title %}Home{% endblock %}
|
||||
|
||||
{# Alpine.js component - uses shopLayoutData() from shop-layout.js #}
|
||||
{% block alpine_data %}shopLayoutData(){% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
|
||||
{# Hero Section #}
|
||||
<div class="hero-section rounded-lg mb-12">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4">
|
||||
Welcome to {{ vendor.name }}
|
||||
</h1>
|
||||
{% if vendor.tagline %}
|
||||
<p class="text-xl md:text-2xl mb-6 opacity-90">
|
||||
{{ vendor.tagline }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if vendor.description %}
|
||||
<p class="text-lg mb-8 opacity-80 max-w-2xl mx-auto">
|
||||
{{ vendor.description }}
|
||||
</p>
|
||||
{% endif %}
|
||||
<a href="{{ base_url }}products" class="inline-block bg-white text-gray-900 px-8 py-3 rounded-lg font-semibold hover:bg-gray-100 transition">
|
||||
Shop Now
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{# Featured Categories (if you have categories) #}
|
||||
<div class="mb-12">
|
||||
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-200 mb-6">
|
||||
Shop by Category
|
||||
</h2>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{# Placeholder categories - will be loaded via API in future #}
|
||||
<div class="feature-card text-center cursor-pointer">
|
||||
<div class="text-4xl mb-3">🏠</div>
|
||||
<h3 class="font-semibold">Home & Living</h3>
|
||||
</div>
|
||||
<div class="feature-card text-center cursor-pointer">
|
||||
<div class="text-4xl mb-3">👔</div>
|
||||
<h3 class="font-semibold">Fashion</h3>
|
||||
</div>
|
||||
<div class="feature-card text-center cursor-pointer">
|
||||
<div class="text-4xl mb-3">📱</div>
|
||||
<h3 class="font-semibold">Electronics</h3>
|
||||
</div>
|
||||
<div class="feature-card text-center cursor-pointer">
|
||||
<div class="text-4xl mb-3">🎨</div>
|
||||
<h3 class="font-semibold">Arts & Crafts</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Featured Products Section #}
|
||||
<div class="mb-12">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-200">
|
||||
Featured Products
|
||||
</h2>
|
||||
<a href="{{ base_url }}products" class="text-primary hover:underline font-medium">
|
||||
View All →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{# Loading State #}
|
||||
<div x-show="loading" class="flex justify-center items-center py-12">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
|
||||
{# Products Grid #}
|
||||
<div x-show="!loading" class="product-grid">
|
||||
{# Coming Soon Notice #}
|
||||
<div class="col-span-full text-center py-12 bg-white dark:bg-gray-800 rounded-lg border-2 border-dashed border-gray-300 dark:border-gray-600">
|
||||
<div class="text-6xl mb-4">🛍️</div>
|
||||
<h3 class="text-2xl font-semibold text-gray-700 dark:text-gray-200 mb-2">
|
||||
Products Coming Soon
|
||||
</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
We're setting up our shop. Check back soon for amazing products!
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-500">
|
||||
<strong>For Developers:</strong> Products will be loaded dynamically from the API once you add them to the database.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Why Shop With Us Section #}
|
||||
<div class="mb-12">
|
||||
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-200 mb-6 text-center">
|
||||
Why Shop With Us
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="feature-card text-center">
|
||||
<div class="text-5xl mb-4">🚚</div>
|
||||
<h3 class="text-xl font-semibold mb-2">Fast Shipping</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
Quick and reliable delivery to your doorstep
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-card text-center">
|
||||
<div class="text-5xl mb-4">🔒</div>
|
||||
<h3 class="text-xl font-semibold mb-2">Secure Payment</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
Your transactions are safe and encrypted
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-card text-center">
|
||||
<div class="text-5xl mb-4">💝</div>
|
||||
<h3 class="text-xl font-semibold mb-2">Quality Guarantee</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
100% satisfaction guaranteed on all products
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
// Future: Load featured products from API
|
||||
// Example:
|
||||
// document.addEventListener('alpine:init', () => {
|
||||
// Alpine.data('shopHome', () => ({
|
||||
// ...shopLayoutData(),
|
||||
// featuredProducts: [],
|
||||
// loading: true,
|
||||
//
|
||||
// async init() {
|
||||
// await this.loadFeaturedProducts();
|
||||
// },
|
||||
//
|
||||
// async loadFeaturedProducts() {
|
||||
// try {
|
||||
// const response = await fetch('/api/v1/shop/products?featured=true&limit=8');
|
||||
// const data = await response.json();
|
||||
// this.featuredProducts = data.products;
|
||||
// } catch (error) {
|
||||
// console.error('Failed to load products:', error);
|
||||
// } finally {
|
||||
// this.loading = false;
|
||||
// }
|
||||
// }
|
||||
// }));
|
||||
// });
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user