fix: replace inline SVGs with $icon() helper (FE-002)

Convert 90 inline SVG icons to use the shared $icon() helper function
across shop and vendor templates for consistency and maintainability.

Templates updated:
- Shop: checkout, products, login, register, forgot/reset-password
- Shop account: addresses, dashboard, messages, order-detail, orders, profile
- Vendor: billing, login, onboarding, team, landing pages (4 variants)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-03 19:47:21 +01:00
parent daec462847
commit 8e539634aa
20 changed files with 103 additions and 294 deletions

View File

@@ -382,10 +382,7 @@
class="px-4 py-2 text-sm font-medium rounded-lg transition-colors">
<template x-if="purchasingAddon === addon.code">
<span class="flex items-center">
<svg class="animate-spin -ml-1 mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="-ml-1 mr-2 h-4 w-4" x-html="$icon('spinner', 'h-4 w-4 animate-spin')"></span>
Processing...
</span>
</template>

View File

@@ -1,4 +1,5 @@
{# app/templates/vendor/landing-default.html #}
{# standalone #}
{# Default/Minimal Landing Page Template #}
{% extends "shop/base.html" %}
@@ -39,9 +40,7 @@
class="inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg text-white bg-primary hover:bg-primary-dark transition-colors shadow-lg hover:shadow-xl"
style="background-color: var(--color-primary)">
Browse Our Shop
<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="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
<span class="w-5 h-5 ml-2" x-html="$icon('arrow-right', 'w-5 h-5')"></span>
</a>
{% if page.content %}
<a href="#about"

View File

@@ -1,4 +1,5 @@
{# app/templates/vendor/landing-full.html #}
{# standalone #}
{# Full Landing Page Template - Maximum Features #}
{% extends "shop/base.html" %}
@@ -46,9 +47,7 @@
class="inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg text-white bg-primary hover:bg-primary-dark transition-colors shadow-lg"
style="background-color: var(--color-primary)">
Shop Now
<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"></path>
</svg>
<span class="w-5 h-5 ml-2" x-html="$icon('arrow-right', 'w-5 h-5')"></span>
</a>
<a href="#about"
class="inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors border-2 border-gray-200 dark:border-gray-600">
@@ -108,9 +107,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
<div class="p-6 rounded-xl bg-gray-50 dark:bg-gray-800 hover:shadow-lg transition-shadow">
<div class="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center mb-4" style="color: var(--color-primary)">
<svg 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="M5 13l4 4L19 7"></path>
</svg>
<span class="w-6 h-6" x-html="$icon('check', 'w-6 h-6')"></span>
</div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
Premium Quality
@@ -122,9 +119,7 @@
<div class="p-6 rounded-xl bg-gray-50 dark:bg-gray-800 hover:shadow-lg transition-shadow">
<div class="w-12 h-12 rounded-lg bg-accent/10 flex items-center justify-center mb-4" style="color: var(--color-accent)">
<svg 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="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<span class="w-6 h-6" x-html="$icon('bolt', 'w-6 h-6')"></span>
</div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
Fast Shipping
@@ -136,9 +131,7 @@
<div class="p-6 rounded-xl bg-gray-50 dark:bg-gray-800 hover:shadow-lg transition-shadow">
<div class="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center mb-4" style="color: var(--color-primary)">
<svg 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="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="w-6 h-6" x-html="$icon('currency-dollar', 'w-6 h-6')"></span>
</div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
Best Value
@@ -150,9 +143,7 @@
<div class="p-6 rounded-xl bg-gray-50 dark:bg-gray-800 hover:shadow-lg transition-shadow">
<div class="w-12 h-12 rounded-lg bg-accent/10 flex items-center justify-center mb-4" style="color: var(--color-accent)">
<svg 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="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path>
</svg>
<span class="w-6 h-6" x-html="$icon('user-plus', 'w-6 h-6')"></span>
</div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
24/7 Support
@@ -258,9 +249,7 @@
<a href="{{ base_url }}shop/products"
class="inline-flex items-center justify-center px-10 py-5 text-lg font-bold rounded-xl text-primary bg-white hover:bg-gray-50 transition-all transform hover:scale-105 shadow-2xl">
View All Products
<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="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
<span class="w-5 h-5 ml-2" x-html="$icon('arrow-right', 'w-5 h-5')"></span>
</a>
</div>
</section>

View File

@@ -1,4 +1,5 @@
{# app/templates/vendor/landing-minimal.html #}
{# standalone #}
{# Minimal Landing Page Template - Ultra Clean #}
{% extends "shop/base.html" %}
@@ -40,9 +41,7 @@
class="inline-flex items-center justify-center px-10 py-5 text-xl font-semibold rounded-full text-white bg-primary hover:bg-primary-dark transition-all transform hover:scale-105 shadow-2xl"
style="background-color: var(--color-primary)">
Enter Shop
<svg class="w-6 h-6 ml-3" 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"></path>
</svg>
<span class="w-6 h-6 ml-3" x-html="$icon('arrow-right', 'w-6 h-6')"></span>
</a>
</div>

View File

@@ -1,4 +1,5 @@
{# app/templates/vendor/landing-modern.html #}
{# standalone #}
{# Modern Landing Page Template - Feature Rich #}
{% extends "shop/base.html" %}
@@ -43,9 +44,7 @@
class="group inline-flex items-center justify-center px-10 py-5 text-lg font-bold rounded-xl text-white bg-primary hover:bg-primary-dark transition-all transform hover:scale-105 shadow-2xl hover:shadow-3xl"
style="background-color: var(--color-primary)">
<span>Start Shopping</span>
<svg class="w-5 h-5 ml-2 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
<span class="w-5 h-5 ml-2 group-hover:translate-x-1 transition-transform" x-html="$icon('arrow-right', 'w-5 h-5')"></span>
</a>
<a href="#features"
class="inline-flex items-center justify-center px-10 py-5 text-lg font-bold rounded-xl text-gray-700 dark:text-gray-200 bg-white/90 dark:bg-gray-800/90 backdrop-blur hover:bg-white dark:hover:bg-gray-800 transition-all border-2 border-gray-200 dark:border-gray-600">
@@ -55,9 +54,7 @@
{# Scroll Indicator #}
<div class="absolute bottom-10 left-1/2 transform -translate-x-1/2 animate-bounce">
<svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
</svg>
<span class="w-6 h-6 text-gray-400" x-html="$icon('arrow-down', 'w-6 h-6')"></span>
</div>
</div>
</section>
@@ -79,9 +76,7 @@
<div class="text-center group">
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-primary/10 text-primary mb-6 group-hover:scale-110 transition-transform"
style="color: var(--color-primary)">
<svg class="w-10 h-10" 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>
<span class="w-10 h-10" x-html="$icon('check', 'w-10 h-10')"></span>
</div>
<h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
Quality Products
@@ -95,9 +90,7 @@
<div class="text-center group">
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-accent/10 text-accent mb-6 group-hover:scale-110 transition-transform"
style="color: var(--color-accent)">
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<span class="w-10 h-10" x-html="$icon('bolt', 'w-10 h-10')"></span>
</div>
<h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
Fast Delivery
@@ -111,9 +104,7 @@
<div class="text-center group">
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-primary/10 text-primary mb-6 group-hover:scale-110 transition-transform"
style="color: var(--color-primary)">
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="w-10 h-10" x-html="$icon('currency-dollar', 'w-10 h-10')"></span>
</div>
<h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">
Best Prices
@@ -149,9 +140,7 @@
<a href="{{ base_url }}shop/products"
class="inline-flex items-center justify-center px-10 py-5 text-lg font-bold rounded-xl text-primary bg-white hover:bg-gray-50 transition-all transform hover:scale-105 shadow-2xl">
Browse Products
<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="M9 5l7 7-7 7"></path>
</svg>
<span class="w-5 h-5 ml-2" x-html="$icon('chevron-right', 'w-5 h-5')"></span>
</a>
</div>
</section>

View File

@@ -88,10 +88,7 @@
class="block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple disabled:opacity-50 disabled:cursor-not-allowed">
<span x-show="!loading">Sign in</span>
<span x-show="loading" class="flex items-center justify-center">
<svg class="inline w-4 h-4 mr-2 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="inline w-4 h-4 mr-2" x-html="$icon('spinner', 'w-4 h-4 animate-spin')"></span>
Signing in...
</span>
</button>
@@ -116,10 +113,7 @@
<!-- Loading State -->
<div x-show="loading && !vendor" class="text-center py-8">
<svg class="inline w-8 h-8 animate-spin text-purple-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="inline-block w-8 h-8 text-purple-600" x-html="$icon('spinner', 'w-8 h-8 animate-spin')"></span>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Loading vendor information...</p>
</div>

View File

@@ -1,4 +1,5 @@
{# app/templates/vendor/onboarding.html #}
{# standalone #}
<!DOCTYPE html>
<html :class="{ 'dark': dark }" x-data="vendorOnboarding()" lang="en">
<head>
@@ -35,9 +36,7 @@
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>
<span class="w-4 h-4 text-gray-500" x-html="$icon('chevron-down', 'w-4 h-4')"></span>
</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">
@@ -67,9 +66,7 @@
'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-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>
<span class="w-4 h-4 sm:w-5 sm:h-5" x-html="$icon('check', 'w-4 h-4 sm:w-5 sm:h-5')"></span>
</template>
<template x-if="!isStepCompleted(step.id)">
<span x-text="index + 1"></span>
@@ -95,10 +92,7 @@
<div class="max-w-4xl mx-auto bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden">
<!-- Loading State -->
<div x-show="loading" class="p-12 text-center">
<svg class="inline w-8 h-8 animate-spin text-purple-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="inline-block w-8 h-8 text-purple-600" x-html="$icon('spinner', 'w-8 h-8 animate-spin')"></span>
<p class="mt-4 text-gray-600 dark:text-gray-400" x-text="t('loading')"></p>
</div>
@@ -222,23 +216,16 @@
class="px-4 py-2 text-sm font-medium text-purple-600 bg-purple-100 rounded-lg hover:bg-purple-200 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed">
<span x-show="!testing" x-text="t('step2.test_connection')"></span>
<span x-show="testing" class="flex items-center">
<svg class="w-4 h-4 mr-2 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="w-4 h-4 mr-2" x-html="$icon('spinner', 'w-4 h-4 animate-spin')"></span>
<span x-text="t('step2.testing')"></span>
</span>
</button>
<span x-show="connectionStatus === 'success'" class="text-green-600 dark:text-green-400 text-sm flex items-center">
<svg class="w-4 h-4 mr-1" 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>
<span class="w-4 h-4 mr-1" x-html="$icon('check', 'w-4 h-4')"></span>
<span x-text="t('step2.connection_success')"></span>
</span>
<span x-show="connectionStatus === 'failed'" class="text-red-600 dark:text-red-400 text-sm flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
<span class="w-4 h-4 mr-1" x-html="$icon('x-mark', 'w-4 h-4')"></span>
<span x-text="connectionError || t('step2.connection_failed')"></span>
</span>
</div>
@@ -348,9 +335,7 @@
<!-- After Sync -->
<div x-show="syncComplete" class="text-center py-8">
<div class="w-16 h-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
<svg class="w-8 h-8 text-green-600 dark:text-green-400" 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>
<span class="w-8 h-8 text-green-600 dark:text-green-400" x-html="$icon('check', 'w-8 h-8')"></span>
</div>
<p class="text-lg font-medium text-gray-800 dark:text-white" x-text="t('step4.import_complete')"></p>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
@@ -376,10 +361,7 @@
<span x-text="currentStep === 'order_sync' && syncComplete ? t('buttons.complete') : t('buttons.save_continue')"></span>
</span>
<span x-show="saving" class="flex items-center">
<svg class="w-4 h-4 mr-2 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<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"></path>
</svg>
<span class="w-4 h-4 mr-2" x-html="$icon('spinner', 'w-4 h-4 animate-spin')"></span>
<span x-text="t('buttons.saving')"></span>
</span>
</button>

View File

@@ -111,17 +111,22 @@
></span>
</td>
<!-- Joined -->
<td class="px-4 py-3 text-sm" x-text="formatDate(member.created_at)"></td>
<td class="px-4 py-3 text-sm" x-text="formatDate(member.joined_at)"></td>
<!-- Actions -->
<td class="px-4 py-3">
<div class="flex items-center space-x-2 text-sm">
<!-- Edit button - not for owners -->
<button
@click="openEditModal(member)"
class="p-1 text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400"
title="Edit"
x-show="!member.is_owner"
>
<span x-html="$icon('pencil', 'w-5 h-5')"></span>
</button>
<!-- Owner badge -->
<span x-show="member.is_owner" class="text-xs text-gray-400 dark:text-gray-500 italic">Owner</span>
<!-- Remove button - not for owners -->
<button
@click="confirmRemove(member)"
class="p-1 text-gray-500 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400"