feat(i18n): complete post-launch i18n phases 5-8
Some checks failed
Some checks failed
- Phase 5: Translate homepage-modern.html (~90 new locale keys, all hardcoded strings replaced with _() calls for dashboard mock, features, pricing tiers, testimonial sections) - Phase 6: Translate homepage-minimal.html (17 new locale keys for fallback content, features, and CTA sections) - Phase 7: Add multi-language page.title/content support with title_translations and content_translations JSON columns, Alembic migration cms_002, translated title/content resolution in templates, and seed script updates with tt() helper - Phase 8: Complete lb.json audit — fill 6 missing keys (messages, confirmations), also backfill same keys in fr.json and de.json All 4 locale files now have 340 keys with full parity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
{# 3-Step Signup Wizard: Plan → Account → Payment #}
|
||||
{% extends "platform/base.html" %}
|
||||
|
||||
{% block title %}Start Your Free Trial - Orion{% endblock %}
|
||||
{% block title %}{{ _("cms.platform.signup.page_title") }} - {{ platform.name if platform else 'Orion' }}{% endblock %}
|
||||
|
||||
{% block extra_head %}
|
||||
{# Stripe.js for payment #}
|
||||
@@ -16,7 +16,7 @@
|
||||
{# Progress Steps #}
|
||||
<div class="mb-12">
|
||||
<div class="flex items-center justify-between">
|
||||
<template x-for="(stepName, index) in ['Select Plan', 'Account', 'Payment']" :key="index">
|
||||
<template x-for="(stepName, index) in ['{{ _("cms.platform.signup.step_plan") }}', '{{ _("cms.platform.signup.step_account") }}', '{{ _("cms.platform.signup.step_payment") }}']" :key="index">
|
||||
<div class="flex items-center" :class="index < 2 ? 'flex-1' : ''">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full font-semibold transition-colors"
|
||||
:class="currentStep > index + 1 ? 'bg-green-500 text-white' : currentStep === index + 1 ? 'bg-indigo-600 text-white' : 'bg-gray-200 dark:bg-gray-700 text-gray-500'">
|
||||
@@ -50,11 +50,11 @@
|
||||
STEP 1: SELECT PLAN
|
||||
=============================================================== #}
|
||||
<div x-show="currentStep === 1" class="p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">Choose Your Plan</h2>
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">{{ _("cms.platform.signup.choose_plan") }}</h2>
|
||||
|
||||
{# Billing Toggle #}
|
||||
<div class="flex items-center justify-center mb-8 space-x-4">
|
||||
<span :class="!isAnnual ? 'font-semibold text-gray-900 dark:text-white' : 'text-gray-500'">Monthly</span>
|
||||
<span :class="!isAnnual ? 'font-semibold text-gray-900 dark:text-white' : 'text-gray-500'">{{ _("cms.platform.pricing.monthly") }}</span>
|
||||
<button @click="isAnnual = !isAnnual"
|
||||
class="relative w-12 h-6 rounded-full transition-colors"
|
||||
:class="isAnnual ? 'bg-indigo-600' : 'bg-gray-300'">
|
||||
@@ -62,7 +62,7 @@
|
||||
:class="isAnnual ? 'translate-x-6' : ''"></span>
|
||||
</button>
|
||||
<span :class="isAnnual ? 'font-semibold text-gray-900 dark:text-white' : 'text-gray-500'">
|
||||
Annual <span class="text-green-600 text-xs">Save 17%</span>
|
||||
{{ _("cms.platform.pricing.annual") }} <span class="text-green-600 text-xs">{{ _("cms.platform.signup.save_percent", percent=17) }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -80,17 +80,17 @@
|
||||
<div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white">{{ tier.name }}</h3>
|
||||
<p class="text-sm text-gray-500">
|
||||
{% if tier.orders_per_month %}{{ tier.orders_per_month }} orders/mo{% else %}Unlimited{% endif %}
|
||||
{% if tier.orders_per_month %}{{ tier.orders_per_month }} {{ _("cms.platform.signup.orders_per_month") }}{% else %}{{ _("cms.platform.signup.unlimited") }}{% endif %}
|
||||
•
|
||||
{% if tier.team_members %}{{ tier.team_members }} user{% if tier.team_members > 1 %}s{% endif %}{% else %}Unlimited{% endif %}
|
||||
{% if tier.team_members %}{{ tier.team_members }} {{ _("cms.platform.signup.team_members", count=tier.team_members) }}{% else %}{{ _("cms.platform.signup.unlimited") }}{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<template x-if="!isAnnual">
|
||||
<span class="text-xl font-bold text-gray-900 dark:text-white">{{ tier.price_monthly|int }}€/mo</span>
|
||||
<span class="text-xl font-bold text-gray-900 dark:text-white">{{ tier.price_monthly|int }}€{{ _("cms.platform.signup.per_month_short") }}</span>
|
||||
</template>
|
||||
<template x-if="isAnnual">
|
||||
<span class="text-xl font-bold text-gray-900 dark:text-white">{{ ((tier.price_annual or tier.price_monthly * 12) / 12)|round(0)|int }}€/mo</span>
|
||||
<span class="text-xl font-bold text-gray-900 dark:text-white">{{ ((tier.price_annual or tier.price_monthly * 12) / 12)|round(0)|int }}€{{ _("cms.platform.signup.per_month_short") }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,15 +103,15 @@
|
||||
{# Free Trial Note #}
|
||||
<div class="mt-6 p-4 bg-green-50 dark:bg-green-900/20 rounded-xl">
|
||||
<p class="text-sm text-green-800 dark:text-green-300">
|
||||
<strong>{{ trial_days }}-day free trial.</strong>
|
||||
We'll collect your payment info, but you won't be charged until the trial ends.
|
||||
<strong>{{ trial_days }}-{{ _("cms.platform.signup.trial_info_days") }}</strong>
|
||||
{{ _("cms.platform.signup.trial_info") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button @click="startSignup()"
|
||||
:disabled="!selectedTier || loading"
|
||||
class="mt-8 w-full py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl transition-colors disabled:opacity-50">
|
||||
Continue
|
||||
{{ _("cms.platform.signup.continue") }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -119,23 +119,23 @@
|
||||
STEP 2: CREATE ACCOUNT
|
||||
=============================================================== #}
|
||||
<div x-show="currentStep === 2" class="p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Create Your Account</h2>
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">{{ _("cms.platform.signup.create_account") }}</h2>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
|
||||
<span class="text-red-500">*</span> Required fields
|
||||
<span class="text-red-500">*</span> {{ _("cms.platform.signup.required_fields") }}
|
||||
</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
First Name <span class="text-red-500">*</span>
|
||||
{{ _("cms.platform.signup.first_name") }} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="text" x-model="account.firstName" required
|
||||
class="w-full 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"/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Last Name <span class="text-red-500">*</span>
|
||||
{{ _("cms.platform.signup.last_name") }} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="text" x-model="account.lastName" required
|
||||
class="w-full 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"/>
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Business Name <span class="text-red-500">*</span>
|
||||
{{ _("cms.platform.signup.merchant_name") }} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="text" x-model="account.merchantName" required
|
||||
class="w-full 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"/>
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Email <span class="text-red-500">*</span>
|
||||
{{ _("cms.platform.signup.email") }} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="email" x-model="account.email" required
|
||||
class="w-full 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"/>
|
||||
@@ -160,11 +160,11 @@
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Password <span class="text-red-500">*</span>
|
||||
{{ _("cms.platform.signup.password") }} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="password" x-model="account.password" required minlength="8"
|
||||
class="w-full 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"/>
|
||||
<p class="text-xs text-gray-500 mt-1">Minimum 8 characters</p>
|
||||
<p class="text-xs text-gray-500 mt-1">{{ _("cms.platform.signup.password_hint") }}</p>
|
||||
</div>
|
||||
|
||||
<template x-if="accountError">
|
||||
@@ -177,12 +177,12 @@
|
||||
<div class="mt-8 flex gap-4">
|
||||
<button @click="currentStep = 1"
|
||||
class="flex-1 py-3 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 font-semibold rounded-xl">
|
||||
Back
|
||||
{{ _("cms.platform.signup.back") }}
|
||||
</button>
|
||||
<button @click="createAccount()"
|
||||
:disabled="loading || !isAccountValid()"
|
||||
class="flex-1 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl disabled:opacity-50">
|
||||
Continue to Payment
|
||||
{{ _("cms.platform.signup.continue_payment") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -191,8 +191,8 @@
|
||||
STEP 3: PAYMENT
|
||||
=============================================================== #}
|
||||
<div x-show="currentStep === 3" class="p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Add Payment Method</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-6">You won't be charged until your {{ trial_days }}-day trial ends.</p>
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">{{ _("cms.platform.signup.add_payment") }}</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-6">{{ _("cms.platform.signup.no_charge_note", trial_days=trial_days) }}</p>
|
||||
|
||||
{# Stripe Card Element #}
|
||||
<div id="card-element" class="p-4 border border-gray-300 dark:border-gray-600 rounded-xl bg-gray-50 dark:bg-gray-900"></div>
|
||||
@@ -201,16 +201,16 @@
|
||||
<div class="mt-8 flex gap-4">
|
||||
<button @click="currentStep = 2"
|
||||
class="flex-1 py-3 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 font-semibold rounded-xl">
|
||||
Back
|
||||
{{ _("cms.platform.signup.back") }}
|
||||
</button>
|
||||
<button @click="submitPayment()"
|
||||
:disabled="loading || paymentProcessing"
|
||||
class="flex-1 py-3 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-xl disabled:opacity-50">
|
||||
<template x-if="paymentProcessing">
|
||||
<span>Processing...</span>
|
||||
<span>{{ _("cms.platform.signup.processing") }}</span>
|
||||
</template>
|
||||
<template x-if="!paymentProcessing">
|
||||
<span>Start Free Trial</span>
|
||||
<span>{{ _("cms.platform.signup.start_trial") }}</span>
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
@@ -224,6 +224,13 @@
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
function signupWizard() {
|
||||
const MSGS = {
|
||||
failedStart: '{{ _("cms.platform.signup.error_start") }}',
|
||||
failedAccount: '{{ _("cms.platform.signup.error_account") }}',
|
||||
paymentNotConfigured: '{{ _("cms.platform.signup.error_payment_config") }}',
|
||||
paymentFailed: '{{ _("cms.platform.signup.error_payment") }}',
|
||||
};
|
||||
|
||||
return {
|
||||
currentStep: 1,
|
||||
loading: false,
|
||||
@@ -286,11 +293,11 @@ function signupWizard() {
|
||||
this.sessionId = data.session_id;
|
||||
this.currentStep = 2;
|
||||
} else {
|
||||
alert(data.detail || 'Failed to start signup');
|
||||
alert(data.detail || MSGS.failedStart);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
alert('Failed to start signup. Please try again.');
|
||||
alert(MSGS.failedStart);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -326,11 +333,11 @@ function signupWizard() {
|
||||
if (response.ok) {
|
||||
this.currentStep = 3;
|
||||
} else {
|
||||
this.accountError = data.detail || 'Failed to create account';
|
||||
this.accountError = data.detail || MSGS.failedAccount;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
this.accountError = 'Failed to create account. Please try again.';
|
||||
this.accountError = MSGS.failedAccount;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -379,7 +386,7 @@ function signupWizard() {
|
||||
|
||||
async submitPayment() {
|
||||
if (!this.stripe || !this.clientSecret) {
|
||||
alert('Payment not configured. Please contact support.');
|
||||
alert(MSGS.paymentNotConfigured);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -416,11 +423,11 @@ function signupWizard() {
|
||||
}
|
||||
window.location.href = '/signup/success?store_code=' + data.store_code;
|
||||
} else {
|
||||
alert(data.detail || 'Failed to complete signup');
|
||||
alert(data.detail || MSGS.paymentFailed);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Payment error:', error);
|
||||
alert('Payment failed. Please try again.');
|
||||
alert(MSGS.paymentFailed);
|
||||
} finally {
|
||||
this.paymentProcessing = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user