refactor: rename shop to storefront for consistency
Rename all "shop" directories and references to "storefront" to match the API and route naming convention already in use. Renamed directories: - app/templates/shop/ → app/templates/storefront/ - static/shop/ → static/storefront/ - app/templates/shared/macros/shop/ → .../macros/storefront/ - docs/frontend/shop/ → docs/frontend/storefront/ Renamed files: - shop.css → storefront.css - shop-layout.js → storefront-layout.js Updated references in: - app/routes/storefront_pages.py (21 template references) - app/modules/cms/routes/pages/vendor.py - app/templates/storefront/base.html (static paths) - All storefront templates (extends/includes) - docs/architecture/frontend-structure.md This aligns the template/static naming with: - Route file: storefront_pages.py - API directory: app/api/v1/storefront/ - Module routes: */routes/api/storefront.py - URL paths: /storefront/* Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
436
app/templates/shared/macros/storefront/trust-badges.html
Normal file
436
app/templates/shared/macros/storefront/trust-badges.html
Normal file
@@ -0,0 +1,436 @@
|
||||
{#
|
||||
Trust Badge Components
|
||||
======================
|
||||
Trust signals and security indicators for e-commerce.
|
||||
|
||||
Usage:
|
||||
{% from 'shared/macros/shop/trust-badges.html' import trust_badges, trust_banner, payment_icons, guarantee_badge %}
|
||||
#}
|
||||
|
||||
|
||||
{#
|
||||
Trust Badges
|
||||
============
|
||||
Grid of trust indicators.
|
||||
|
||||
Parameters:
|
||||
- badges: List of badge types to show (default: all)
|
||||
- layout: 'grid' | 'inline' | 'vertical' (default: 'grid')
|
||||
- size: 'sm' | 'md' | 'lg' (default: 'md')
|
||||
- show_text: Show badge text (default: true)
|
||||
- free_shipping_threshold: Threshold for free shipping (default: none)
|
||||
|
||||
Badge Types:
|
||||
- secure_payment
|
||||
- free_shipping
|
||||
- easy_returns
|
||||
- support_24_7
|
||||
- money_back
|
||||
- ssl_secured
|
||||
- fast_delivery
|
||||
- quality_guarantee
|
||||
|
||||
Usage:
|
||||
{{ trust_badges(badges=['secure_payment', 'free_shipping', 'easy_returns']) }}
|
||||
{{ trust_badges(layout='inline', size='sm') }}
|
||||
#}
|
||||
{% macro trust_badges(
|
||||
badges=none,
|
||||
layout='grid',
|
||||
size='md',
|
||||
show_text=true,
|
||||
free_shipping_threshold=none
|
||||
) %}
|
||||
{% set all_badges = [
|
||||
{
|
||||
'id': 'secure_payment',
|
||||
'icon': 'lock-closed',
|
||||
'title': 'Secure Payment',
|
||||
'description': '256-bit SSL encryption'
|
||||
},
|
||||
{
|
||||
'id': 'free_shipping',
|
||||
'icon': 'truck',
|
||||
'title': 'Free Shipping',
|
||||
'description': 'On orders over $' ~ (free_shipping_threshold or 50)
|
||||
},
|
||||
{
|
||||
'id': 'easy_returns',
|
||||
'icon': 'refresh',
|
||||
'title': 'Easy Returns',
|
||||
'description': '30-day return policy'
|
||||
},
|
||||
{
|
||||
'id': 'support_24_7',
|
||||
'icon': 'support',
|
||||
'title': '24/7 Support',
|
||||
'description': 'Always here to help'
|
||||
},
|
||||
{
|
||||
'id': 'money_back',
|
||||
'icon': 'cash',
|
||||
'title': 'Money Back',
|
||||
'description': '100% guarantee'
|
||||
},
|
||||
{
|
||||
'id': 'ssl_secured',
|
||||
'icon': 'shield-check',
|
||||
'title': 'SSL Secured',
|
||||
'description': 'Protected checkout'
|
||||
},
|
||||
{
|
||||
'id': 'fast_delivery',
|
||||
'icon': 'lightning-bolt',
|
||||
'title': 'Fast Delivery',
|
||||
'description': '2-5 business days'
|
||||
},
|
||||
{
|
||||
'id': 'quality_guarantee',
|
||||
'icon': 'badge-check',
|
||||
'title': 'Quality Guarantee',
|
||||
'description': 'Premium products'
|
||||
}
|
||||
] %}
|
||||
{% set selected_badges = badges if badges else ['secure_payment', 'free_shipping', 'easy_returns', 'support_24_7'] %}
|
||||
{% set sizes = {
|
||||
'sm': {'icon': 'w-5 h-5', 'title': 'text-xs', 'desc': 'text-xs', 'padding': 'p-2', 'gap': 'gap-1'},
|
||||
'md': {'icon': 'w-6 h-6', 'title': 'text-sm', 'desc': 'text-xs', 'padding': 'p-3', 'gap': 'gap-2'},
|
||||
'lg': {'icon': 'w-8 h-8', 'title': 'text-base', 'desc': 'text-sm', 'padding': 'p-4', 'gap': 'gap-3'}
|
||||
} %}
|
||||
{% set layouts = {
|
||||
'grid': 'grid grid-cols-2 md:grid-cols-4 gap-4',
|
||||
'inline': 'flex flex-wrap items-center justify-center gap-6',
|
||||
'vertical': 'flex flex-col gap-3'
|
||||
} %}
|
||||
|
||||
<div class="{{ layouts[layout] }}">
|
||||
{% for badge_id in selected_badges %}
|
||||
{% for badge in all_badges %}
|
||||
{% if badge.id == badge_id %}
|
||||
<div class="flex items-center {{ sizes[size].gap }} {{ sizes[size].padding if layout == 'grid' else '' }} {{ 'bg-gray-50 dark:bg-gray-800 rounded-lg' if layout == 'grid' else '' }}">
|
||||
<div class="flex-shrink-0 text-purple-600 dark:text-purple-400">
|
||||
<span x-html="$icon('{{ badge.icon }}', '{{ sizes[size].icon }}')"></span>
|
||||
</div>
|
||||
{% if show_text %}
|
||||
<div class="{{ 'min-w-0' if layout == 'grid' else '' }}">
|
||||
<p class="font-medium text-gray-900 dark:text-white {{ sizes[size].title }} {{ 'truncate' if layout == 'grid' else '' }}">{{ badge.title }}</p>
|
||||
{% if layout != 'inline' %}
|
||||
<p class="text-gray-500 dark:text-gray-400 {{ sizes[size].desc }} {{ 'truncate' if layout == 'grid' else '' }}">{{ badge.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Trust Banner
|
||||
============
|
||||
Full-width trust banner for product pages or checkout.
|
||||
|
||||
Parameters:
|
||||
- variant: 'default' | 'compact' | 'detailed' (default: 'default')
|
||||
- show_icons: Show payment/security icons (default: true)
|
||||
|
||||
Usage:
|
||||
{{ trust_banner() }}
|
||||
{{ trust_banner(variant='compact') }}
|
||||
#}
|
||||
{% macro trust_banner(
|
||||
variant='default',
|
||||
show_icons=true
|
||||
) %}
|
||||
{% if variant == 'compact' %}
|
||||
<div class="flex flex-wrap items-center justify-center gap-6 py-4 text-sm text-gray-600 dark:text-gray-400">
|
||||
<span class="flex items-center gap-2">
|
||||
<span x-html="$icon('truck', 'w-5 h-5 text-purple-600 dark:text-purple-400')"></span>
|
||||
Free shipping over $50
|
||||
</span>
|
||||
<span class="flex items-center gap-2">
|
||||
<span x-html="$icon('refresh', 'w-5 h-5 text-purple-600 dark:text-purple-400')"></span>
|
||||
30-day returns
|
||||
</span>
|
||||
<span class="flex items-center gap-2">
|
||||
<span x-html="$icon('shield-check', 'w-5 h-5 text-purple-600 dark:text-purple-400')"></span>
|
||||
Secure checkout
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{% elif variant == 'detailed' %}
|
||||
<div class="bg-gradient-to-r from-purple-50 to-indigo-50 dark:from-purple-900/20 dark:to-indigo-900/20 rounded-xl p-6">
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
<div class="text-center">
|
||||
<div class="w-12 h-12 mx-auto mb-3 bg-purple-100 dark:bg-purple-900/30 rounded-full flex items-center justify-center">
|
||||
<span x-html="$icon('truck', 'w-6 h-6 text-purple-600 dark:text-purple-400')"></span>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-1">Free Shipping</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">On all orders over $50. International shipping available.</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="w-12 h-12 mx-auto mb-3 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center">
|
||||
<span x-html="$icon('refresh', 'w-6 h-6 text-green-600 dark:text-green-400')"></span>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-1">Easy Returns</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">30-day hassle-free return policy. No questions asked.</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="w-12 h-12 mx-auto mb-3 bg-blue-100 dark:bg-blue-900/30 rounded-full flex items-center justify-center">
|
||||
<span x-html="$icon('shield-check', 'w-6 h-6 text-blue-600 dark:text-blue-400')"></span>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-1">Secure Payment</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">Your payment info is protected with 256-bit encryption.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% if show_icons %}
|
||||
<div class="mt-6 pt-6 border-t border-purple-200 dark:border-purple-800">
|
||||
{{ payment_icons(size='sm') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
{# Default variant #}
|
||||
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span x-html="$icon('shield-check', 'w-8 h-8 text-green-600 dark:text-green-400')"></span>
|
||||
<div>
|
||||
<p class="font-medium text-gray-900 dark:text-white">Secure Shopping Guarantee</p>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">Shop with confidence - your data is protected</p>
|
||||
</div>
|
||||
</div>
|
||||
{% if show_icons %}
|
||||
{{ payment_icons(size='sm') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Payment Icons
|
||||
=============
|
||||
Display accepted payment method icons.
|
||||
|
||||
Parameters:
|
||||
- methods: List of payment methods (default: common cards)
|
||||
- size: 'xs' | 'sm' | 'md' | 'lg' (default: 'md')
|
||||
- grayscale: Show in grayscale (default: false)
|
||||
|
||||
Methods: visa, mastercard, amex, paypal, apple_pay, google_pay, discover, klarna
|
||||
|
||||
Usage:
|
||||
{{ payment_icons() }}
|
||||
{{ payment_icons(methods=['visa', 'mastercard', 'paypal'], size='lg') }}
|
||||
#}
|
||||
{% macro payment_icons(
|
||||
methods=none,
|
||||
size='md',
|
||||
grayscale=false
|
||||
) %}
|
||||
{% set all_methods = {
|
||||
'visa': {'name': 'Visa', 'color': 'text-blue-600'},
|
||||
'mastercard': {'name': 'Mastercard', 'color': 'text-orange-500'},
|
||||
'amex': {'name': 'American Express', 'color': 'text-blue-500'},
|
||||
'paypal': {'name': 'PayPal', 'color': 'text-blue-700'},
|
||||
'apple_pay': {'name': 'Apple Pay', 'color': 'text-gray-900 dark:text-white'},
|
||||
'google_pay': {'name': 'Google Pay', 'color': 'text-gray-700'},
|
||||
'discover': {'name': 'Discover', 'color': 'text-orange-600'},
|
||||
'klarna': {'name': 'Klarna', 'color': 'text-pink-500'}
|
||||
} %}
|
||||
{% set selected = methods if methods else ['visa', 'mastercard', 'amex', 'paypal'] %}
|
||||
{% set sizes = {
|
||||
'xs': 'h-4',
|
||||
'sm': 'h-6',
|
||||
'md': 'h-8',
|
||||
'lg': 'h-10'
|
||||
} %}
|
||||
|
||||
<div class="flex items-center gap-2 {{ 'grayscale opacity-60' if grayscale else '' }}">
|
||||
{% for method in selected %}
|
||||
{% if method in all_methods %}
|
||||
<div
|
||||
class="px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded {{ sizes[size] }} flex items-center justify-center"
|
||||
title="{{ all_methods[method].name }}"
|
||||
>
|
||||
<span class="text-xs font-bold {{ all_methods[method].color }}">{{ all_methods[method].name[:4] }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Guarantee Badge
|
||||
===============
|
||||
Individual guarantee/warranty badge.
|
||||
|
||||
Parameters:
|
||||
- type: 'money_back' | 'warranty' | 'authentic' | 'satisfaction' (default: 'money_back')
|
||||
- days: Number of days (for money_back/warranty)
|
||||
- size: 'sm' | 'md' | 'lg' (default: 'md')
|
||||
- variant: 'default' | 'outlined' | 'filled' (default: 'default')
|
||||
|
||||
Usage:
|
||||
{{ guarantee_badge(type='money_back', days=30) }}
|
||||
{{ guarantee_badge(type='warranty', days=365, variant='filled') }}
|
||||
#}
|
||||
{% macro guarantee_badge(
|
||||
type='money_back',
|
||||
days=30,
|
||||
size='md',
|
||||
variant='default'
|
||||
) %}
|
||||
{% set badges = {
|
||||
'money_back': {
|
||||
'icon': 'cash',
|
||||
'title': days ~ '-Day Money Back',
|
||||
'subtitle': 'Guarantee'
|
||||
},
|
||||
'warranty': {
|
||||
'icon': 'shield-check',
|
||||
'title': (days // 365) ~ '-Year Warranty' if days >= 365 else days ~ '-Day Warranty',
|
||||
'subtitle': 'Included'
|
||||
},
|
||||
'authentic': {
|
||||
'icon': 'badge-check',
|
||||
'title': '100% Authentic',
|
||||
'subtitle': 'Guaranteed'
|
||||
},
|
||||
'satisfaction': {
|
||||
'icon': 'emoji-happy',
|
||||
'title': 'Satisfaction',
|
||||
'subtitle': 'Guaranteed'
|
||||
}
|
||||
} %}
|
||||
{% set badge = badges[type] %}
|
||||
{% set sizes = {
|
||||
'sm': {'icon': 'w-8 h-8', 'title': 'text-xs', 'subtitle': 'text-xs', 'padding': 'p-3'},
|
||||
'md': {'icon': 'w-10 h-10', 'title': 'text-sm', 'subtitle': 'text-xs', 'padding': 'p-4'},
|
||||
'lg': {'icon': 'w-12 h-12', 'title': 'text-base', 'subtitle': 'text-sm', 'padding': 'p-5'}
|
||||
} %}
|
||||
{% set variants = {
|
||||
'default': 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700',
|
||||
'outlined': 'border-2 border-purple-600 dark:border-purple-400',
|
||||
'filled': 'bg-purple-600 text-white'
|
||||
} %}
|
||||
|
||||
<div class="{{ variants[variant] }} rounded-lg {{ sizes[size].padding }} text-center">
|
||||
<div class="mx-auto mb-2 {{ 'text-purple-600 dark:text-purple-400' if variant != 'filled' else 'text-white' }}">
|
||||
<span x-html="$icon('{{ badge.icon }}', '{{ sizes[size].icon }} mx-auto')"></span>
|
||||
</div>
|
||||
<p class="font-bold {{ sizes[size].title }} {{ 'text-gray-900 dark:text-white' if variant != 'filled' else 'text-white' }}">{{ badge.title }}</p>
|
||||
<p class="{{ sizes[size].subtitle }} {{ 'text-gray-500 dark:text-gray-400' if variant != 'filled' else 'text-purple-100' }}">{{ badge.subtitle }}</p>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Security Seals
|
||||
==============
|
||||
Security certification seals.
|
||||
|
||||
Parameters:
|
||||
- seals: List of seal types to show
|
||||
- layout: 'horizontal' | 'vertical' (default: 'horizontal')
|
||||
|
||||
Seal Types: ssl, pci, mcafee, norton, trustpilot
|
||||
|
||||
Usage:
|
||||
{{ security_seals(seals=['ssl', 'pci']) }}
|
||||
#}
|
||||
{% macro security_seals(
|
||||
seals=none,
|
||||
layout='horizontal'
|
||||
) %}
|
||||
{% set all_seals = [
|
||||
{'id': 'ssl', 'name': 'SSL Secure', 'icon': 'lock-closed'},
|
||||
{'id': 'pci', 'name': 'PCI Compliant', 'icon': 'shield-check'},
|
||||
{'id': 'verified', 'name': 'Verified Business', 'icon': 'badge-check'},
|
||||
{'id': 'secure_checkout', 'name': 'Secure Checkout', 'icon': 'shield-check'}
|
||||
] %}
|
||||
{% set selected = seals if seals else ['ssl', 'verified'] %}
|
||||
|
||||
<div class="flex {{ 'flex-col' if layout == 'vertical' else 'flex-wrap' }} items-center gap-3">
|
||||
{% for seal_id in selected %}
|
||||
{% for seal in all_seals %}
|
||||
{% if seal.id == seal_id %}
|
||||
<div class="flex items-center gap-2 px-3 py-2 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
|
||||
<span x-html="$icon('{{ seal.icon }}', 'w-5 h-5 text-green-600 dark:text-green-400')"></span>
|
||||
<span class="text-sm font-medium text-green-700 dark:text-green-300">{{ seal.name }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{#
|
||||
Checkout Trust Section
|
||||
======================
|
||||
Combined trust elements for checkout pages.
|
||||
|
||||
Parameters:
|
||||
- show_guarantee: Show money-back guarantee (default: true)
|
||||
- show_payment: Show payment icons (default: true)
|
||||
- show_security: Show security seals (default: true)
|
||||
|
||||
Usage:
|
||||
{{ checkout_trust_section() }}
|
||||
#}
|
||||
{% macro checkout_trust_section(
|
||||
show_guarantee=true,
|
||||
show_payment=true,
|
||||
show_security=true
|
||||
) %}
|
||||
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-6 space-y-6">
|
||||
{% if show_guarantee %}
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-14 h-14 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center flex-shrink-0">
|
||||
<span x-html="$icon('shield-check', 'w-8 h-8 text-green-600 dark:text-green-400')"></span>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-gray-900 dark:text-white">100% Secure Checkout</h4>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">Your payment information is encrypted and secure. We never store your card details.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_payment %}
|
||||
<div class="border-t border-gray-200 dark:border-gray-700 pt-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-3">We accept:</p>
|
||||
{{ payment_icons(size='md') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_security %}
|
||||
<div class="border-t border-gray-200 dark:border-gray-700 pt-4">
|
||||
{{ security_seals() }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="border-t border-gray-200 dark:border-gray-700 pt-4">
|
||||
<div class="flex flex-wrap items-center justify-center gap-4 text-xs text-gray-500 dark:text-gray-400">
|
||||
<span class="flex items-center gap-1">
|
||||
<span x-html="$icon('lock-closed', 'w-4 h-4')"></span>
|
||||
256-bit SSL
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span x-html="$icon('refresh', 'w-4 h-4')"></span>
|
||||
30-day returns
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span x-html="$icon('support', 'w-4 h-4')"></span>
|
||||
24/7 support
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
Reference in New Issue
Block a user