feat: add i18n translations to platform marketing website
- Add platform translation keys to all locale files (en, fr, de, lb) - Integrate language selector in platform base template header - Translate homepage-wizamart.html (hero, pricing, addons, find-shop, CTA) - Translate pricing.html, find-shop.html, signup-success.html - Add i18n context to platform routes via get_jinja2_globals() - Support variable interpolation for trial_days, count parameters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.database import get_db
|
||||
from app.utils.i18n import get_jinja2_globals
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -28,7 +29,10 @@ templates = Jinja2Templates(directory=str(TEMPLATES_DIR))
|
||||
|
||||
def get_platform_context(request: Request, db: Session) -> dict:
|
||||
"""Build context for platform pages."""
|
||||
return {
|
||||
# Get language from request state (set by middleware)
|
||||
language = getattr(request.state, "language", "fr")
|
||||
|
||||
context = {
|
||||
"request": request,
|
||||
"platform_name": "Wizamart",
|
||||
"platform_domain": settings.platform_domain,
|
||||
@@ -36,6 +40,11 @@ def get_platform_context(request: Request, db: Session) -> dict:
|
||||
"trial_days": settings.stripe_trial_days,
|
||||
}
|
||||
|
||||
# Add i18n globals (_, t, current_language, SUPPORTED_LANGUAGES, etc.)
|
||||
context.update(get_jinja2_globals(language))
|
||||
|
||||
return context
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Homepage
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{# app/templates/platform/base.html #}
|
||||
{# Base template for platform public pages (homepage, about, faq, etc.) #}
|
||||
{% from 'shared/macros/language_selector.html' import language_selector_compact %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" x-data="platformLayoutData()" x-bind:class="{ 'dark': dark }">
|
||||
<html lang="{{ current_language|default('en') }}" x-data="platformLayoutData()" x-bind:class="{ 'dark': dark }">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -70,13 +71,13 @@
|
||||
<div class="hidden md:flex items-center space-x-8">
|
||||
{# Main Navigation #}
|
||||
<a href="/pricing" class="text-gray-700 dark:text-gray-300 hover:text-indigo-600 dark:hover:text-indigo-400 font-medium transition-colors">
|
||||
Pricing
|
||||
{{ _("platform.nav.pricing") }}
|
||||
</a>
|
||||
<a href="/find-shop" class="text-gray-700 dark:text-gray-300 hover:text-indigo-600 dark:hover:text-indigo-400 font-medium transition-colors">
|
||||
Find Your Shop
|
||||
{{ _("platform.nav.find_shop") }}
|
||||
</a>
|
||||
<a href="/signup" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition-colors">
|
||||
Start Free Trial
|
||||
{{ _("platform.nav.start_trial") }}
|
||||
</a>
|
||||
|
||||
{# Dynamic header navigation from CMS #}
|
||||
@@ -89,11 +90,17 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{# Language selector #}
|
||||
{{ language_selector_compact(
|
||||
current_language=current_language|default('en'),
|
||||
enabled_languages=SUPPORTED_LANGUAGES|default(['en', 'fr', 'de', 'lb'])
|
||||
) }}
|
||||
|
||||
{# Dark mode toggle #}
|
||||
<button
|
||||
@click="toggleDarkMode()"
|
||||
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
|
||||
aria-label="Toggle dark mode"
|
||||
aria-label="{{ _('platform.nav.toggle_dark_mode') }}"
|
||||
>
|
||||
<svg x-show="!dark" class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path>
|
||||
@@ -109,7 +116,7 @@
|
||||
<button
|
||||
@click="mobileMenuOpen = !mobileMenuOpen"
|
||||
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
aria-label="Toggle menu"
|
||||
aria-label="{{ _('platform.nav.toggle_menu') }}"
|
||||
>
|
||||
<svg x-show="!mobileMenuOpen" class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
||||
@@ -156,13 +163,13 @@
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
Lightweight OMS for Letzshop sellers. Manage orders, inventory, and invoicing.
|
||||
{{ _("platform.footer.tagline") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{# Quick Links #}
|
||||
<div>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">Quick Links</h4>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">{{ _("platform.footer.quick_links") }}</h4>
|
||||
<ul class="space-y-2">
|
||||
{% if footer_pages %}
|
||||
{% for page in footer_pages %}
|
||||
@@ -179,16 +186,16 @@
|
||||
|
||||
{# Platform Links #}
|
||||
<div>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">Platform</h4>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">{{ _("platform.footer.platform") }}</h4>
|
||||
<ul class="space-y-2">
|
||||
<li>
|
||||
<a href="/admin/login" class="text-gray-600 dark:text-gray-400 hover:text-primary transition-colors">
|
||||
Admin Login
|
||||
{{ _("platform.nav.admin_login") }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/vendor/wizamart/login" class="text-gray-600 dark:text-gray-400 hover:text-primary transition-colors">
|
||||
Vendor Login
|
||||
{{ _("platform.nav.vendor_login") }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -196,7 +203,7 @@
|
||||
|
||||
{# Contact Info #}
|
||||
<div>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">Contact</h4>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white mb-4">{{ _("platform.footer.contact") }}</h4>
|
||||
<ul class="space-y-2 text-gray-600 dark:text-gray-400 text-sm">
|
||||
<li>support@marketplace.com</li>
|
||||
<li>+1 (555) 123-4567</li>
|
||||
@@ -210,14 +217,14 @@
|
||||
<div class="mt-12 pt-8 border-t border-gray-200 dark:border-gray-700">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center">
|
||||
<p class="text-gray-600 dark:text-gray-400 text-sm">
|
||||
© 2025 Wizamart. Built for Luxembourg e-commerce.
|
||||
{{ _("platform.footer.copyright", year=2025) }}
|
||||
</p>
|
||||
<div class="flex space-x-6 mt-4 md:mt-0">
|
||||
<a href="/privacy" class="text-gray-600 dark:text-gray-400 hover:text-primary text-sm transition-colors">
|
||||
Privacy Policy
|
||||
{{ _("platform.footer.privacy") }}
|
||||
</a>
|
||||
<a href="/terms" class="text-gray-600 dark:text-gray-400 hover:text-primary text-sm transition-colors">
|
||||
Terms of Service
|
||||
{{ _("platform.footer.terms") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{# Letzshop Vendor Finder Page #}
|
||||
{% extends "platform/base.html" %}
|
||||
|
||||
{% block title %}Find Your Shop - Wizamart{% endblock %}
|
||||
{% block title %}{{ _("platform.find_shop.title") }} - Wizamart{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div x-data="vendorFinderData()" class="py-16 lg:py-24">
|
||||
@@ -10,10 +10,10 @@
|
||||
{# Header #}
|
||||
<div class="text-center mb-12">
|
||||
<h1 class="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Find Your Letzshop Shop
|
||||
{{ _("platform.find_shop.title") }}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400">
|
||||
Enter your Letzshop shop URL or search by name to get started.
|
||||
{{ _("platform.find_shop.subtitle") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
type="text"
|
||||
x-model="searchQuery"
|
||||
@keyup.enter="lookupVendor()"
|
||||
placeholder="Enter Letzshop URL or shop name..."
|
||||
placeholder="{{ _('platform.find_shop.search_placeholder') }}"
|
||||
class="flex-1 px-4 py-3 rounded-xl border border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||
/>
|
||||
<button
|
||||
@@ -38,18 +38,18 @@
|
||||
</svg>
|
||||
</template>
|
||||
<template x-if="!loading">
|
||||
<span>Search</span>
|
||||
<span>{{ _("platform.find_shop.search_button") }}</span>
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{# Examples #}
|
||||
<div class="mt-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
<strong>Examples:</strong>
|
||||
<strong>{{ _("platform.find_shop.examples") }}</strong>
|
||||
<ul class="list-disc list-inside mt-1">
|
||||
<li>https://letzshop.lu/vendors/my-shop</li>
|
||||
<li>letzshop.lu/vendors/my-shop</li>
|
||||
<li>my-shop (just the shop name)</li>
|
||||
<li>my-shop</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -61,6 +61,7 @@
|
||||
<div class="p-8">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-green-600 font-medium mb-1">{{ _("platform.find_shop.found") }}</p>
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white" x-text="result.vendor.name"></h2>
|
||||
<a :href="result.vendor.letzshop_url" target="_blank"
|
||||
class="text-indigo-600 dark:text-indigo-400 hover:underline mt-1 inline-block"
|
||||
@@ -81,13 +82,15 @@
|
||||
<template x-if="!result.vendor.is_claimed">
|
||||
<a :href="'/signup?letzshop=' + result.vendor.slug"
|
||||
class="px-8 py-3 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-xl transition-colors">
|
||||
Claim This Shop & Start Free Trial
|
||||
{{ _("platform.find_shop.claim_button") }}
|
||||
</a>
|
||||
</template>
|
||||
<template x-if="result.vendor.is_claimed">
|
||||
<div class="px-6 py-3 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400 rounded-xl">
|
||||
This shop has already been claimed. If this is your shop, please
|
||||
<a href="/contact" class="text-indigo-600 hover:underline">contact support</a>.
|
||||
<span class="inline-flex items-center">
|
||||
<span class="text-yellow-500 mr-2">{{ _("platform.find_shop.claimed_badge") }}</span>
|
||||
</span>
|
||||
{{ _("platform.find_shop.already_claimed") }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -99,12 +102,12 @@
|
||||
<svg class="w-16 h-16 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-2">Shop Not Found</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400" x-text="result.error || 'We could not find a Letzshop shop with that URL. Please check and try again.'"></p>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-2">{{ _("platform.find_shop.not_found") }}</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400" x-text="result.error || '{{ _("platform.find_shop.not_found") }}'"></p>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="/signup" class="text-indigo-600 dark:text-indigo-400 hover:underline">
|
||||
Or sign up without a Letzshop connection →
|
||||
{{ _("platform.find_shop.or_signup") }} →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -114,18 +117,18 @@
|
||||
|
||||
{# Help Section #}
|
||||
<div class="mt-12 text-center">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Need Help?</h3>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">{{ _("platform.find_shop.need_help") }}</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Don't have a Letzshop account yet? No problem!
|
||||
{{ _("platform.find_shop.no_account_yet") }}
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="https://letzshop.lu" target="_blank"
|
||||
class="px-6 py-3 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 font-medium rounded-xl hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||||
Create a Letzshop Account
|
||||
{{ _("platform.find_shop.create_letzshop") }}
|
||||
</a>
|
||||
<a href="/signup"
|
||||
class="px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-xl transition-colors">
|
||||
Sign Up Without Letzshop
|
||||
{{ _("platform.find_shop.signup_without") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,26 +19,24 @@
|
||||
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
30-Day Free Trial - No Credit Card Required to Start
|
||||
{{ _("platform.hero.badge", trial_days=trial_days) }}
|
||||
</div>
|
||||
|
||||
{# Headline #}
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl font-extrabold text-gray-900 dark:text-white leading-tight mb-6">
|
||||
Lightweight OMS for
|
||||
<span class="text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-purple-600">Letzshop Sellers</span>
|
||||
{{ _("platform.hero.title") }}
|
||||
</h1>
|
||||
|
||||
{# Subheadline #}
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400 max-w-3xl mx-auto mb-10">
|
||||
Order management, inventory, and invoicing built for Luxembourg e-commerce.
|
||||
Stop juggling spreadsheets. Start running your business.
|
||||
{{ _("platform.hero.subtitle") }}
|
||||
</p>
|
||||
|
||||
{# CTA Buttons #}
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/signup"
|
||||
class="inline-flex items-center justify-center px-8 py-4 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl shadow-lg shadow-indigo-500/30 transition-all hover:scale-105">
|
||||
Start Free Trial
|
||||
{{ _("platform.hero.cta_trial") }}
|
||||
<svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/>
|
||||
</svg>
|
||||
@@ -48,7 +46,7 @@
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
||||
</svg>
|
||||
Find Your Letzshop Shop
|
||||
{{ _("platform.hero.cta_find_shop") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -69,15 +67,15 @@
|
||||
{# Section Header #}
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-3xl md:text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Simple, Transparent Pricing
|
||||
{{ _("platform.pricing.title") }}
|
||||
</h2>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
|
||||
Choose the plan that fits your business. All plans include a {{ trial_days }}-day free trial.
|
||||
{{ _("platform.pricing.subtitle", trial_days=trial_days) }}
|
||||
</p>
|
||||
|
||||
{# Billing Toggle #}
|
||||
<div class="flex items-center justify-center mt-8 space-x-4">
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': !annual }">Monthly</span>
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': !annual }">{{ _("platform.pricing.monthly") }}</span>
|
||||
<button @click="annual = !annual"
|
||||
class="relative w-14 h-7 rounded-full transition-colors"
|
||||
:class="annual ? 'bg-indigo-600' : 'bg-gray-300 dark:bg-gray-600'">
|
||||
@@ -85,8 +83,8 @@
|
||||
:class="annual ? 'translate-x-7' : ''"></span>
|
||||
</button>
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': annual }">
|
||||
Annual
|
||||
<span class="text-green-600 text-sm font-medium ml-1">Save 2 months!</span>
|
||||
{{ _("platform.pricing.annual") }}
|
||||
<span class="text-green-600 text-sm font-medium ml-1">{{ _("platform.pricing.save_months") }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -101,7 +99,7 @@
|
||||
{% if tier.is_popular %}
|
||||
<div class="absolute -top-3 left-1/2 -translate-x-1/2">
|
||||
<span class="bg-indigo-600 text-white text-xs font-bold px-3 py-1 rounded-full">
|
||||
MOST POPULAR
|
||||
{{ _("platform.pricing.most_popular") }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -114,19 +112,19 @@
|
||||
<template x-if="!annual">
|
||||
<div>
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">{{ tier.price_monthly }}</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">/month</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">{{ _("platform.pricing.per_month") }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template x-if="annual">
|
||||
<div>
|
||||
{% if tier.price_annual %}
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">{{ (tier.price_annual / 12)|round(0)|int }}</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">/month</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">{{ _("platform.pricing.per_month") }}</span>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ tier.price_annual }}/year
|
||||
{{ tier.price_annual }}{{ _("platform.pricing.per_year") }}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="text-2xl font-bold text-gray-900 dark:text-white">Custom</span>
|
||||
<span class="text-2xl font-bold text-gray-900 dark:text-white">{{ _("platform.pricing.custom") }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</template>
|
||||
@@ -139,28 +137,28 @@
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.orders_per_month %}{{ tier.orders_per_month }} orders/month{% else %}Unlimited orders{% endif %}
|
||||
{% if tier.orders_per_month %}{{ _("platform.pricing.orders_per_month", count=tier.orders_per_month) }}{% else %}{{ _("platform.pricing.unlimited_orders") }}{% endif %}
|
||||
</li>
|
||||
{# Products #}
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.products_limit %}{{ tier.products_limit }} products{% else %}Unlimited products{% endif %}
|
||||
{% if tier.products_limit %}{{ _("platform.pricing.products_limit", count=tier.products_limit) }}{% else %}{{ _("platform.pricing.unlimited_products") }}{% endif %}
|
||||
</li>
|
||||
{# Team Members #}
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.team_members %}{{ tier.team_members }} team member{% if tier.team_members > 1 %}s{% endif %}{% else %}Unlimited team{% endif %}
|
||||
{% if tier.team_members %}{{ _("platform.pricing.team_members", count=tier.team_members) }}{% else %}{{ _("platform.pricing.unlimited_team") }}{% endif %}
|
||||
</li>
|
||||
{# Letzshop Sync #}
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
Letzshop order sync
|
||||
{{ _("platform.pricing.letzshop_sync") }}
|
||||
</li>
|
||||
{# Tier-specific features #}
|
||||
{% if 'invoice_eu_vat' in tier.features %}
|
||||
@@ -168,7 +166,7 @@
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
EU VAT invoicing
|
||||
{{ _("platform.pricing.eu_vat_invoicing") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'analytics_dashboard' in tier.features %}
|
||||
@@ -176,7 +174,7 @@
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
Analytics dashboard
|
||||
{{ _("platform.pricing.analytics_dashboard") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'api_access' in tier.features %}
|
||||
@@ -184,7 +182,7 @@
|
||||
<svg class="w-5 h-5 text-green-500 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
API access
|
||||
{{ _("platform.pricing.api_access") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
@@ -193,14 +191,14 @@
|
||||
{% if tier.is_enterprise %}
|
||||
<a href="/contact?tier=enterprise"
|
||||
class="block w-full py-3 px-4 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white font-semibold rounded-xl text-center hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors">
|
||||
Contact Sales
|
||||
{{ _("platform.pricing.contact_sales") }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/signup?tier={{ tier.code }}"
|
||||
:href="'/signup?tier={{ tier.code }}&annual=' + annual"
|
||||
class="block w-full py-3 px-4 font-semibold rounded-xl text-center transition-colors
|
||||
{% if tier.is_popular %}bg-indigo-600 hover:bg-indigo-700 text-white{% else %}bg-indigo-100 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300 hover:bg-indigo-200 dark:hover:bg-indigo-900/50{% endif %}">
|
||||
Start Free Trial
|
||||
{{ _("platform.pricing.start_trial") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -217,10 +215,10 @@
|
||||
{# Section Header #}
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-3xl md:text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Enhance Your Platform
|
||||
{{ _("platform.addons.title") }}
|
||||
</h2>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
|
||||
Add custom branding, professional email, and enhanced security.
|
||||
{{ _("platform.addons.subtitle") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -279,10 +277,10 @@
|
||||
{# Section Header #}
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-3xl md:text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Find Your Letzshop Shop
|
||||
{{ _("platform.find_shop.title") }}
|
||||
</h2>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400">
|
||||
Already selling on Letzshop? Enter your shop URL to get started.
|
||||
{{ _("platform.find_shop.subtitle") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -292,7 +290,7 @@
|
||||
<input
|
||||
type="text"
|
||||
x-model="shopUrl"
|
||||
placeholder="Enter your Letzshop URL (e.g., letzshop.lu/vendors/my-shop)"
|
||||
placeholder="{{ _('platform.find_shop.placeholder') }}"
|
||||
class="flex-1 px-4 py-3 rounded-xl border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||
/>
|
||||
<button
|
||||
@@ -305,7 +303,7 @@
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/>
|
||||
</svg>
|
||||
</template>
|
||||
Find My Shop
|
||||
{{ _("platform.find_shop.button") }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -321,12 +319,12 @@
|
||||
<template x-if="!vendorResult.vendor.is_claimed">
|
||||
<a :href="'/signup?letzshop=' + vendorResult.vendor.slug"
|
||||
class="px-6 py-2 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-lg transition-colors">
|
||||
Claim This Shop
|
||||
{{ _("platform.find_shop.claim_shop") }}
|
||||
</a>
|
||||
</template>
|
||||
<template x-if="vendorResult.vendor.is_claimed">
|
||||
<span class="px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400 rounded-lg">
|
||||
Already Claimed
|
||||
{{ _("platform.find_shop.already_claimed") }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
@@ -341,7 +339,7 @@
|
||||
|
||||
{# Help Text #}
|
||||
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400 text-center">
|
||||
Don't have a Letzshop account? <a href="https://letzshop.lu" target="_blank" class="text-indigo-600 dark:text-indigo-400 hover:underline">Sign up with Letzshop first</a>, then come back to connect your shop.
|
||||
{{ _("platform.find_shop.no_account") }} <a href="https://letzshop.lu" target="_blank" class="text-indigo-600 dark:text-indigo-400 hover:underline">{{ _("platform.find_shop.signup_letzshop") }}</a>{{ _("platform.find_shop.then_connect") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -353,15 +351,14 @@
|
||||
<section class="py-16 lg:py-24 bg-gradient-to-r from-indigo-600 to-purple-600">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-3xl md:text-4xl font-bold text-white mb-6">
|
||||
Ready to Streamline Your Orders?
|
||||
{{ _("platform.cta.title") }}
|
||||
</h2>
|
||||
<p class="text-xl text-indigo-100 mb-10">
|
||||
Join Letzshop vendors who trust Wizamart for their order management.
|
||||
Start your {{ trial_days }}-day free trial today.
|
||||
{{ _("platform.cta.subtitle", trial_days=trial_days) }}
|
||||
</p>
|
||||
<a href="/signup"
|
||||
class="inline-flex items-center px-10 py-4 bg-white text-indigo-600 font-bold rounded-xl shadow-lg hover:shadow-xl transition-all hover:scale-105">
|
||||
Start Free Trial
|
||||
{{ _("platform.cta.button") }}
|
||||
<svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/>
|
||||
</svg>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{# Standalone Pricing Page #}
|
||||
{% extends "platform/base.html" %}
|
||||
|
||||
{% block title %}Pricing - Wizamart{% endblock %}
|
||||
{% block title %}{{ _("platform.pricing.title") }} - Wizamart{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div x-data="{ annual: false }" class="py-16 lg:py-24">
|
||||
@@ -10,15 +10,15 @@
|
||||
{# Header #}
|
||||
<div class="text-center mb-12">
|
||||
<h1 class="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Choose Your Plan
|
||||
{{ _("platform.pricing.title") }}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
|
||||
All plans include a {{ trial_days }}-day free trial. No credit card required to start.
|
||||
{{ _("platform.pricing.trial_note", trial_days=trial_days) }}
|
||||
</p>
|
||||
|
||||
{# Billing Toggle #}
|
||||
<div class="flex items-center justify-center mt-8 space-x-4">
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': !annual }">Monthly</span>
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': !annual }">{{ _("platform.pricing.monthly") }}</span>
|
||||
<button @click="annual = !annual"
|
||||
class="relative w-14 h-7 rounded-full transition-colors"
|
||||
:class="annual ? 'bg-indigo-600' : 'bg-gray-300 dark:bg-gray-600'">
|
||||
@@ -26,8 +26,8 @@
|
||||
:class="annual ? 'translate-x-7' : ''"></span>
|
||||
</button>
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': annual }">
|
||||
Annual
|
||||
<span class="text-green-600 text-sm font-medium ml-1">Save 2 months!</span>
|
||||
{{ _("platform.pricing.annual") }}
|
||||
<span class="text-green-600 text-sm font-medium ml-1">{{ _("platform.pricing.save_months") }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
{% if tier.is_popular %}
|
||||
<div class="absolute -top-3 left-1/2 -translate-x-1/2">
|
||||
<span class="bg-indigo-600 text-white text-xs font-bold px-3 py-1 rounded-full">RECOMMENDED</span>
|
||||
<span class="bg-indigo-600 text-white text-xs font-bold px-3 py-1 rounded-full">{{ _("platform.pricing.recommended") }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -50,17 +50,17 @@
|
||||
<template x-if="!annual">
|
||||
<div>
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">{{ tier.price_monthly }}</span>
|
||||
<span class="text-gray-500">/month</span>
|
||||
<span class="text-gray-500">{{ _("platform.pricing.per_month") }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template x-if="annual">
|
||||
<div>
|
||||
{% if tier.price_annual %}
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">{{ (tier.price_annual / 12)|round(0)|int }}</span>
|
||||
<span class="text-gray-500">/month</span>
|
||||
<div class="text-sm text-gray-500">Billed {{ tier.price_annual }}/year</div>
|
||||
<span class="text-gray-500">{{ _("platform.pricing.per_month") }}</span>
|
||||
<div class="text-sm text-gray-500">{{ tier.price_annual }}{{ _("platform.pricing.per_year") }}</div>
|
||||
{% else %}
|
||||
<span class="text-2xl font-bold text-gray-900 dark:text-white">Custom Pricing</span>
|
||||
<span class="text-2xl font-bold text-gray-900 dark:text-white">{{ _("platform.pricing.custom") }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</template>
|
||||
@@ -71,37 +71,37 @@
|
||||
<svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.orders_per_month %}{{ tier.orders_per_month }} orders/month{% else %}Unlimited orders{% endif %}
|
||||
{% if tier.orders_per_month %}{{ _("platform.pricing.orders_per_month", count=tier.orders_per_month) }}{% else %}{{ _("platform.pricing.unlimited_orders") }}{% endif %}
|
||||
</li>
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.products_limit %}{{ tier.products_limit }} products{% else %}Unlimited products{% endif %}
|
||||
{% if tier.products_limit %}{{ _("platform.pricing.products_limit", count=tier.products_limit) }}{% else %}{{ _("platform.pricing.unlimited_products") }}{% endif %}
|
||||
</li>
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.team_members %}{{ tier.team_members }} team member{% if tier.team_members > 1 %}s{% endif %}{% else %}Unlimited team{% endif %}
|
||||
{% if tier.team_members %}{{ _("platform.pricing.team_members", count=tier.team_members) }}{% else %}{{ _("platform.pricing.unlimited_team") }}{% endif %}
|
||||
</li>
|
||||
<li class="flex items-center text-gray-700 dark:text-gray-300">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% if tier.order_history_months %}{{ tier.order_history_months }} months history{% else %}Unlimited history{% endif %}
|
||||
{{ _("platform.pricing.letzshop_sync") }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% if tier.is_enterprise %}
|
||||
<a href="/contact" class="block w-full py-3 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white font-semibold rounded-xl text-center hover:bg-gray-300 transition-colors">
|
||||
Contact Sales
|
||||
{{ _("platform.pricing.contact_sales") }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a :href="'/signup?tier={{ tier.code }}&annual=' + annual"
|
||||
class="block w-full py-3 font-semibold rounded-xl text-center transition-colors
|
||||
{% if tier.is_popular %}bg-indigo-600 hover:bg-indigo-700 text-white{% else %}bg-indigo-100 text-indigo-700 hover:bg-indigo-200{% endif %}">
|
||||
Start Free Trial
|
||||
{{ _("platform.pricing.start_trial") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -111,7 +111,7 @@
|
||||
{# Back to Home #}
|
||||
<div class="text-center mt-12">
|
||||
<a href="/" class="text-indigo-600 dark:text-indigo-400 hover:underline">
|
||||
← Back to Home
|
||||
← {{ _("platform.pricing.back_home") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{# Signup Success Page #}
|
||||
{% extends "platform/base.html" %}
|
||||
|
||||
{% block title %}Welcome to Wizamart!{% endblock %}
|
||||
{% block title %}{{ _("platform.success.title") }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="min-h-screen py-16 bg-gray-50 dark:bg-gray-900 flex items-center justify-center">
|
||||
@@ -17,23 +17,23 @@
|
||||
|
||||
{# Welcome Message #}
|
||||
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Welcome to Wizamart!
|
||||
{{ _("platform.success.title") }}
|
||||
</h1>
|
||||
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400 mb-8">
|
||||
Your account has been created and your {{ trial_days }}-day free trial has started.
|
||||
{{ _("platform.success.subtitle", trial_days=trial_days) }}
|
||||
</p>
|
||||
|
||||
{# Next Steps #}
|
||||
<div class="bg-white dark:bg-gray-800 rounded-2xl p-8 border border-gray-200 dark:border-gray-700 text-left mb-8">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">What's Next?</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">{{ _("platform.success.what_next") }}</h2>
|
||||
<ul class="space-y-4">
|
||||
<li class="flex items-start">
|
||||
<div class="w-6 h-6 bg-indigo-100 dark:bg-indigo-900/30 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||
<span class="text-indigo-600 dark:text-indigo-400 text-sm font-bold">1</span>
|
||||
</div>
|
||||
<span class="ml-3 text-gray-700 dark:text-gray-300">
|
||||
<strong>Connect Letzshop:</strong> Add your API key to start syncing orders automatically.
|
||||
<strong>{{ _("platform.success.step_connect") }}</strong> {{ _("platform.success.step_connect_desc") }}
|
||||
</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
@@ -41,7 +41,7 @@
|
||||
<span class="text-indigo-600 dark:text-indigo-400 text-sm font-bold">2</span>
|
||||
</div>
|
||||
<span class="ml-3 text-gray-700 dark:text-gray-300">
|
||||
<strong>Set Up Invoicing:</strong> Configure your invoice settings for Luxembourg compliance.
|
||||
<strong>{{ _("platform.success.step_invoicing") }}</strong> {{ _("platform.success.step_invoicing_desc") }}
|
||||
</span>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
@@ -49,7 +49,7 @@
|
||||
<span class="text-indigo-600 dark:text-indigo-400 text-sm font-bold">3</span>
|
||||
</div>
|
||||
<span class="ml-3 text-gray-700 dark:text-gray-300">
|
||||
<strong>Import Products:</strong> Sync your product catalog from Letzshop.
|
||||
<strong>{{ _("platform.success.step_products") }}</strong> {{ _("platform.success.step_products_desc") }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -59,7 +59,7 @@
|
||||
{% if vendor_code %}
|
||||
<a href="/vendor/{{ vendor_code }}/dashboard"
|
||||
class="inline-flex items-center px-8 py-4 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl shadow-lg transition-all hover:scale-105">
|
||||
Go to Dashboard
|
||||
{{ _("platform.success.go_to_dashboard") }}
|
||||
<svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"/>
|
||||
</svg>
|
||||
@@ -67,14 +67,14 @@
|
||||
{% else %}
|
||||
<a href="/admin/login"
|
||||
class="inline-flex items-center px-8 py-4 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl shadow-lg transition-all">
|
||||
Login to Dashboard
|
||||
{{ _("platform.success.login_dashboard") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{# Support Link #}
|
||||
<p class="mt-8 text-gray-500 dark:text-gray-400">
|
||||
Need help getting started?
|
||||
<a href="/contact" class="text-indigo-600 dark:text-indigo-400 hover:underline">Contact our support team</a>
|
||||
{{ _("platform.success.need_help") }}
|
||||
<a href="/contact" class="text-indigo-600 dark:text-indigo-400 hover:underline">{{ _("platform.success.contact_support") }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user