fix: improve onboarding UX and fix order sync error
- Remove redundant 1/4 progress counter from header - Make step indicators mobile-friendly (smaller circles, hidden labels) - Add CSV URL help text pointing to Letzshop Admin > API > Export Products - Fix AttributeError in order sync progress (use correct model attributes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -541,28 +541,31 @@ class OnboardingService:
|
||||
elif job.status == "failed":
|
||||
progress = 0
|
||||
elif job.status == "processing":
|
||||
if job.total_shipments and job.total_shipments > 0:
|
||||
progress = int((job.processed_shipments or 0) / job.total_shipments * 100)
|
||||
# Use orders_processed and shipments_fetched for progress
|
||||
total = job.shipments_fetched or 0
|
||||
processed = job.orders_processed or 0
|
||||
if total > 0:
|
||||
progress = int(processed / total * 100)
|
||||
else:
|
||||
progress = 50 # Indeterminate
|
||||
elif job.status == "fetching":
|
||||
# Show partial progress during fetch phase
|
||||
if job.total_pages and job.total_pages > 0:
|
||||
progress = int((job.current_page or 0) / job.total_pages * 50)
|
||||
else:
|
||||
progress = 25 # Indeterminate
|
||||
|
||||
# Determine current phase
|
||||
current_phase = None
|
||||
if job.status == "fetching":
|
||||
current_phase = "fetching"
|
||||
elif job.status == "processing":
|
||||
current_phase = "orders"
|
||||
elif job.status == "completed":
|
||||
current_phase = "complete"
|
||||
current_phase = job.current_phase or job.status
|
||||
|
||||
return {
|
||||
"job_id": job.id,
|
||||
"status": job.status,
|
||||
"progress_percentage": progress,
|
||||
"current_phase": current_phase,
|
||||
"orders_imported": job.processed_shipments or 0,
|
||||
"orders_total": job.total_shipments,
|
||||
"products_imported": 0, # TODO: Track this
|
||||
"orders_imported": job.orders_imported or 0,
|
||||
"orders_total": job.shipments_fetched,
|
||||
"products_imported": job.products_matched or 0,
|
||||
"started_at": job.started_at,
|
||||
"completed_at": job.completed_at,
|
||||
"estimated_remaining_seconds": None, # TODO: Calculate
|
||||
|
||||
56
app/templates/vendor/onboarding.html
vendored
56
app/templates/vendor/onboarding.html
vendored
@@ -23,51 +23,45 @@
|
||||
</div>
|
||||
<span class="text-xl font-semibold text-gray-800 dark:text-white">Wizamart</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Language Selector -->
|
||||
<div class="relative" x-data="{ open: false }">
|
||||
<button @click="open = !open"
|
||||
class="flex items-center space-x-2 px-3 py-2 rounded-lg bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-600 transition-colors">
|
||||
<span x-text="languageFlags[lang]"></span>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300" x-text="languageNames[lang]"></span>
|
||||
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open" @click.away="open = false" x-cloak
|
||||
class="absolute right-0 mt-2 w-40 bg-white dark:bg-gray-700 rounded-lg shadow-lg border border-gray-200 dark:border-gray-600 z-50">
|
||||
<template x-for="langCode in availableLanguages" :key="langCode">
|
||||
<button @click="setLang(langCode); open = false"
|
||||
class="w-full flex items-center space-x-2 px-4 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-600 first:rounded-t-lg last:rounded-b-lg"
|
||||
:class="{ 'bg-purple-50 dark:bg-purple-900/20': lang === langCode }">
|
||||
<span x-text="languageFlags[langCode]"></span>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300" x-text="languageNames[langCode]"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Progress -->
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<span x-text="completedSteps"></span> / 4
|
||||
<!-- Language Selector -->
|
||||
<div class="relative" x-data="{ open: false }">
|
||||
<button @click="open = !open"
|
||||
class="flex items-center space-x-2 px-3 py-2 rounded-lg bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-600 transition-colors">
|
||||
<span x-text="languageFlags[lang]"></span>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300 hidden sm:inline" x-text="languageNames[lang]"></span>
|
||||
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open" @click.away="open = false" x-cloak
|
||||
class="absolute right-0 mt-2 w-40 bg-white dark:bg-gray-700 rounded-lg shadow-lg border border-gray-200 dark:border-gray-600 z-50">
|
||||
<template x-for="langCode in availableLanguages" :key="langCode">
|
||||
<button @click="setLang(langCode); open = false"
|
||||
class="w-full flex items-center space-x-2 px-4 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-600 first:rounded-t-lg last:rounded-b-lg"
|
||||
:class="{ 'bg-purple-50 dark:bg-purple-900/20': lang === langCode }">
|
||||
<span x-text="languageFlags[langCode]"></span>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300" x-text="languageNames[langCode]"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Indicator -->
|
||||
<div class="max-w-4xl mx-auto mb-8">
|
||||
<div class="max-w-4xl mx-auto mb-8 px-2 sm:px-0">
|
||||
<div class="flex items-center justify-between">
|
||||
<template x-for="(step, index) in steps" :key="step.id">
|
||||
<div class="flex items-center" :class="{ 'flex-1': index < steps.length - 1 }">
|
||||
<!-- Step Circle -->
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold transition-all duration-200"
|
||||
<div class="w-8 h-8 sm:w-10 sm:h-10 rounded-full flex items-center justify-center text-xs sm:text-sm font-semibold transition-all duration-200"
|
||||
:class="{
|
||||
'bg-purple-600 text-white': isStepCompleted(step.id) || currentStep === step.id,
|
||||
'bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-400': !isStepCompleted(step.id) && currentStep !== step.id
|
||||
}">
|
||||
<template x-if="isStepCompleted(step.id)">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -75,12 +69,12 @@
|
||||
<span x-text="index + 1"></span>
|
||||
</template>
|
||||
</div>
|
||||
<span class="mt-2 text-xs font-medium text-gray-600 dark:text-gray-400 text-center w-24"
|
||||
<span class="mt-2 text-xs font-medium text-gray-600 dark:text-gray-400 text-center w-16 sm:w-24 hidden sm:block"
|
||||
x-text="step.title"></span>
|
||||
</div>
|
||||
<!-- Connector Line -->
|
||||
<template x-if="index < steps.length - 1">
|
||||
<div class="flex-1 h-1 mx-4 rounded"
|
||||
<div class="flex-1 h-1 mx-1 sm:mx-4 rounded"
|
||||
:class="{
|
||||
'bg-purple-600': isStepCompleted(step.id),
|
||||
'bg-gray-200 dark:bg-gray-700': !isStepCompleted(step.id)
|
||||
|
||||
6
static/vendor/js/onboarding.js
vendored
6
static/vendor/js/onboarding.js
vendored
@@ -61,7 +61,7 @@ const onboardingTranslations = {
|
||||
csv_url_fr: 'French CSV URL',
|
||||
csv_url_en: 'English CSV URL',
|
||||
csv_url_de: 'German CSV URL',
|
||||
csv_url_help: 'At least one CSV URL is required',
|
||||
csv_url_help: 'Find your CSV URL in Letzshop Admin Panel > API > Export Products',
|
||||
default_tax_rate: 'Default Tax Rate (%)',
|
||||
delivery_method: 'Delivery Method',
|
||||
delivery_package: 'Package Delivery',
|
||||
@@ -139,7 +139,7 @@ const onboardingTranslations = {
|
||||
csv_url_fr: 'URL CSV Français',
|
||||
csv_url_en: 'URL CSV Anglais',
|
||||
csv_url_de: 'URL CSV Allemand',
|
||||
csv_url_help: 'Au moins une URL CSV est requise',
|
||||
csv_url_help: 'Trouvez votre URL CSV dans Letzshop Admin > API > Exporter Produits',
|
||||
default_tax_rate: 'Taux de TVA par Défaut (%)',
|
||||
delivery_method: 'Méthode de Livraison',
|
||||
delivery_package: 'Livraison Colis',
|
||||
@@ -217,7 +217,7 @@ const onboardingTranslations = {
|
||||
csv_url_fr: 'Französische CSV-URL',
|
||||
csv_url_en: 'Englische CSV-URL',
|
||||
csv_url_de: 'Deutsche CSV-URL',
|
||||
csv_url_help: 'Mindestens eine CSV-URL ist erforderlich',
|
||||
csv_url_help: 'Finden Sie Ihre CSV-URL im Letzshop Admin-Panel > API > Produkte exportieren',
|
||||
default_tax_rate: 'Standard-Steuersatz (%)',
|
||||
delivery_method: 'Liefermethode',
|
||||
delivery_package: 'Paketlieferung',
|
||||
|
||||
Reference in New Issue
Block a user