fix: improve platform homepage pricing UI and restore footer links
- Fix toggle button alignment with consistent min-widths - Add € currency signs to all prices - Show all tier features with greyed unavailable ones - Add multi-channel integration feature for Enterprise tier - Change Contact Sales to mailto link (fixes 404) - Restore footer CMS page links (About, FAQ, Contact) - Add footer link translations for all 4 languages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,10 @@ def get_platform_context(request: Request, db: Session) -> dict:
|
||||
# Get language from request state (set by middleware)
|
||||
language = getattr(request.state, "language", "fr")
|
||||
|
||||
# Get translation function
|
||||
i18n_globals = get_jinja2_globals(language)
|
||||
t = i18n_globals["t"]
|
||||
|
||||
context = {
|
||||
"request": request,
|
||||
"platform_name": "Wizamart",
|
||||
@@ -41,7 +45,14 @@ def get_platform_context(request: Request, db: Session) -> dict:
|
||||
}
|
||||
|
||||
# Add i18n globals (_, t, current_language, SUPPORTED_LANGUAGES, etc.)
|
||||
context.update(get_jinja2_globals(language))
|
||||
context.update(i18n_globals)
|
||||
|
||||
# Add footer CMS pages
|
||||
context["footer_pages"] = [
|
||||
{"slug": "about", "title": t("platform.footer.about")},
|
||||
{"slug": "faq", "title": t("platform.footer.faq")},
|
||||
{"slug": "contact", "title": t("platform.footer.contact_us")},
|
||||
]
|
||||
|
||||
return context
|
||||
|
||||
|
||||
@@ -74,15 +74,15 @@
|
||||
</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 }">{{ _("platform.pricing.monthly") }}</span>
|
||||
<div class="flex items-center justify-center mt-8 gap-4">
|
||||
<span class="text-gray-700 dark:text-gray-300 min-w-[70px] text-right" :class="{ 'font-semibold': !annual }">{{ _("platform.pricing.monthly") }}</span>
|
||||
<button @click="annual = !annual"
|
||||
class="relative w-14 h-7 rounded-full transition-colors"
|
||||
class="relative w-14 h-7 rounded-full transition-colors flex-shrink-0"
|
||||
:class="annual ? 'bg-indigo-600' : 'bg-gray-300 dark:bg-gray-600'">
|
||||
<span class="absolute top-1 left-1 w-5 h-5 bg-white rounded-full shadow transition-transform"
|
||||
:class="annual ? 'translate-x-7' : ''"></span>
|
||||
</button>
|
||||
<span class="text-gray-700 dark:text-gray-300" :class="{ 'font-semibold': annual }">
|
||||
<span class="text-gray-700 dark:text-gray-300 min-w-[150px]" :class="{ 'font-semibold': annual }">
|
||||
{{ _("platform.pricing.annual") }}
|
||||
<span class="text-green-600 text-sm font-medium ml-1">{{ _("platform.pricing.save_months") }}</span>
|
||||
</span>
|
||||
@@ -111,17 +111,17 @@
|
||||
<div class="mb-6">
|
||||
<template x-if="!annual">
|
||||
<div>
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">{{ tier.price_monthly }}</span>
|
||||
<span class="text-4xl font-extrabold text-gray-900 dark:text-white">€{{ tier.price_monthly|int }}</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-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">{{ _("platform.pricing.per_month") }}</span>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ tier.price_annual }}{{ _("platform.pricing.per_year") }}
|
||||
€{{ tier.price_annual|int }}{{ _("platform.pricing.per_year") }}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="text-2xl font-bold text-gray-900 dark:text-white">{{ _("platform.pricing.custom") }}</span>
|
||||
@@ -130,66 +130,93 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
{# Features List #}
|
||||
<ul class="space-y-3 mb-8">
|
||||
{# Features List - Show all features, grey out unavailable #}
|
||||
<ul class="space-y-2 mb-8 text-sm">
|
||||
{# Orders #}
|
||||
<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">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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 %}{{ _("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">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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 %}{{ _("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">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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 %}{{ _("platform.pricing.team_members", count=tier.team_members) }}{% else %}{{ _("platform.pricing.unlimited_team") }}{% endif %}
|
||||
</li>
|
||||
{# Letzshop Sync #}
|
||||
{# Letzshop Sync - always included #}
|
||||
<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">
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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>
|
||||
{{ _("platform.pricing.letzshop_sync") }}
|
||||
</li>
|
||||
{# Tier-specific features #}
|
||||
{% if 'invoice_eu_vat' in tier.features %}
|
||||
<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">
|
||||
{# EU VAT Invoicing #}
|
||||
<li class="flex items-center {% if 'invoice_eu_vat' in tier.features %}text-gray-700 dark:text-gray-300{% else %}text-gray-400 dark:text-gray-600{% endif %}">
|
||||
{% if 'invoice_eu_vat' in tier.features %}
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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>
|
||||
{% else %}
|
||||
<svg class="w-4 h-4 text-gray-300 dark:text-gray-600 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
{{ _("platform.pricing.eu_vat_invoicing") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'analytics_dashboard' in tier.features %}
|
||||
<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">
|
||||
{# Analytics Dashboard #}
|
||||
<li class="flex items-center {% if 'analytics_dashboard' in tier.features %}text-gray-700 dark:text-gray-300{% else %}text-gray-400 dark:text-gray-600{% endif %}">
|
||||
{% if 'analytics_dashboard' in tier.features %}
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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>
|
||||
{% else %}
|
||||
<svg class="w-4 h-4 text-gray-300 dark:text-gray-600 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
{{ _("platform.pricing.analytics_dashboard") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if 'api_access' in tier.features %}
|
||||
<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">
|
||||
{# API Access #}
|
||||
<li class="flex items-center {% if 'api_access' in tier.features %}text-gray-700 dark:text-gray-300{% else %}text-gray-400 dark:text-gray-600{% endif %}">
|
||||
{% if 'api_access' in tier.features %}
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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>
|
||||
{% else %}
|
||||
<svg class="w-4 h-4 text-gray-300 dark:text-gray-600 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
{{ _("platform.pricing.api_access") }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{# Multi-channel Integration - Enterprise only #}
|
||||
<li class="flex items-center {% if tier.is_enterprise %}text-gray-700 dark:text-gray-300{% else %}text-gray-400 dark:text-gray-600{% endif %}">
|
||||
{% if tier.is_enterprise %}
|
||||
<svg class="w-4 h-4 text-green-500 mr-2 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>
|
||||
{% else %}
|
||||
<svg class="w-4 h-4 text-gray-300 dark:text-gray-600 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
{{ _("platform.pricing.multi_channel") }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{# CTA Button #}
|
||||
{% if tier.is_enterprise %}
|
||||
<a href="/contact?tier=enterprise"
|
||||
<a href="mailto:sales@wizamart.com?subject=Enterprise%20Plan%20Inquiry"
|
||||
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">
|
||||
{{ _("platform.pricing.contact_sales") }}
|
||||
</a>
|
||||
|
||||
@@ -512,6 +512,7 @@
|
||||
"eu_vat_invoicing": "EU-MwSt-Rechnungen",
|
||||
"analytics_dashboard": "Analyse-Dashboard",
|
||||
"api_access": "API-Zugang",
|
||||
"multi_channel": "Multi-Channel-Integration",
|
||||
"products": "Produkte",
|
||||
"team_member": "Teammitglied",
|
||||
"unlimited": "Unbegrenzt",
|
||||
@@ -631,7 +632,10 @@
|
||||
"contact": "Kontakt",
|
||||
"copyright": "© {year} Wizamart. Entwickelt für den luxemburgischen E-Commerce.",
|
||||
"privacy": "Datenschutzerklärung",
|
||||
"terms": "Nutzungsbedingungen"
|
||||
"terms": "Nutzungsbedingungen",
|
||||
"about": "Über uns",
|
||||
"faq": "FAQ",
|
||||
"contact_us": "Kontaktieren Sie uns"
|
||||
},
|
||||
"modern": {
|
||||
"badge_integration": "Offizielle Integration",
|
||||
|
||||
@@ -512,6 +512,7 @@
|
||||
"eu_vat_invoicing": "EU VAT invoicing",
|
||||
"analytics_dashboard": "Analytics dashboard",
|
||||
"api_access": "API access",
|
||||
"multi_channel": "Multi-channel integration",
|
||||
"products": "products",
|
||||
"team_member": "team member",
|
||||
"unlimited": "Unlimited",
|
||||
@@ -631,7 +632,10 @@
|
||||
"contact": "Contact",
|
||||
"copyright": "© {year} Wizamart. Built for Luxembourg e-commerce.",
|
||||
"privacy": "Privacy Policy",
|
||||
"terms": "Terms of Service"
|
||||
"terms": "Terms of Service",
|
||||
"about": "About Us",
|
||||
"faq": "FAQ",
|
||||
"contact_us": "Contact Us"
|
||||
},
|
||||
"modern": {
|
||||
"badge_integration": "Official Integration",
|
||||
|
||||
@@ -512,6 +512,7 @@
|
||||
"eu_vat_invoicing": "Facturation TVA UE",
|
||||
"analytics_dashboard": "Tableau de bord analytique",
|
||||
"api_access": "Accès API",
|
||||
"multi_channel": "Intégration multi-canal",
|
||||
"products": "produits",
|
||||
"team_member": "membre d'équipe",
|
||||
"unlimited": "Illimité",
|
||||
@@ -631,7 +632,10 @@
|
||||
"contact": "Contact",
|
||||
"copyright": "© {year} Wizamart. Conçu pour le e-commerce luxembourgeois.",
|
||||
"privacy": "Politique de confidentialité",
|
||||
"terms": "Conditions d'utilisation"
|
||||
"terms": "Conditions d'utilisation",
|
||||
"about": "À propos",
|
||||
"faq": "FAQ",
|
||||
"contact_us": "Nous contacter"
|
||||
},
|
||||
"modern": {
|
||||
"badge_integration": "Intégration officielle",
|
||||
|
||||
@@ -512,6 +512,7 @@
|
||||
"eu_vat_invoicing": "EU TVA Rechnungen",
|
||||
"analytics_dashboard": "Analyse Dashboard",
|
||||
"api_access": "API Zougang",
|
||||
"multi_channel": "Multi-Channel Integratioun",
|
||||
"products": "Produkter",
|
||||
"team_member": "Teammember",
|
||||
"unlimited": "Onbegrenzt",
|
||||
@@ -631,7 +632,10 @@
|
||||
"contact": "Kontakt",
|
||||
"copyright": "© {year} Wizamart. Gemaach fir de lëtzebuergeschen E-Commerce.",
|
||||
"privacy": "Dateschutzrichtlinn",
|
||||
"terms": "Notzungsbedéngungen"
|
||||
"terms": "Notzungsbedéngungen",
|
||||
"about": "Iwwer eis",
|
||||
"faq": "FAQ",
|
||||
"contact_us": "Kontaktéiert eis"
|
||||
},
|
||||
"modern": {
|
||||
"badge_integration": "Offiziell Integratioun",
|
||||
|
||||
Reference in New Issue
Block a user