184 lines
8.8 KiB
Twig
184 lines
8.8 KiB
Twig
{% extends 'base.twig' %}
|
|
|
|
{# --- METADATA & SEO --- #}
|
|
{% block title %}{{'shop.title'|trans}}{% endblock %}
|
|
{% block meta_description %}{{'shop.description'|trans}}{% endblock %}
|
|
{% block canonical_url %}<link rel="canonical" href="{{ url('app_shop') }}" />{% endblock %}
|
|
|
|
{% block breadcrumb_schema %}
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "BreadcrumbList",
|
|
"itemListElement": [
|
|
{
|
|
"@type": "ListItem",
|
|
"position": 1,
|
|
"name": "{{ 'breadcrumb.home'|trans }}",
|
|
"item": "{{ app.request.schemeAndHttpHost }}"
|
|
},
|
|
{
|
|
"@type": "ListItem",
|
|
"position": 2,
|
|
"name": "{{ 'breadcrumb.shop'|trans }}",
|
|
"item": "{{ app.request.schemeAndHttpHost }}{{ app.request.pathInfo }}"
|
|
}
|
|
]
|
|
}
|
|
</script>
|
|
{% for product in featuredProducts %}
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org/",
|
|
"@type": "ImageObject",
|
|
"contentUrl": "{{ vich_uploader_asset(product,'image') | imagine_filter('webp') }}",
|
|
"license": "https://example.com/license",
|
|
"acquireLicensePage": "{{ app.request.schemeAndHttpHost}}{{ path('app_legal') }}",
|
|
"creditText": "E-Cosplay",
|
|
"creator": {
|
|
"@type": "Person",
|
|
"name": "E-Cosplay"
|
|
},
|
|
"copyrightNotice": "E-Cosplay"
|
|
}}
|
|
</script>
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org/",
|
|
"@type": "Product",
|
|
"name": "{{ product.name }}",
|
|
"image": "{{ vich_uploader_asset(product,'image') | imagine_filter('webp') }}",
|
|
"description": "{{ product.shortDescription }}",
|
|
"sku": "EC-{{ product.id }}",
|
|
"brand": {
|
|
"@type": "Brand",
|
|
"name": "E-COSPLAY"
|
|
},
|
|
"shippingDetails": {
|
|
"@type": "OfferShippingDetails",
|
|
"shippingRate": {
|
|
"@type": "MonetaryAmount",
|
|
"value": 6.00,
|
|
"currency": "EUR"
|
|
},
|
|
"shippingDestination": {
|
|
"@type": "DefinedRegion",
|
|
"addressCountry": "FR"
|
|
},
|
|
"deliveryTime": {
|
|
"@type": "ShippingDeliveryTime",
|
|
"handlingTime": {
|
|
"@type": "QuantitativeValue",
|
|
"minValue": 0,
|
|
"maxValue": 1,
|
|
"unitCode": "DAY"
|
|
},
|
|
"transitTime": {
|
|
"@type": "QuantitativeValue",
|
|
"minValue": 1,
|
|
"maxValue": 5,
|
|
"unitCode": "DAY"
|
|
}
|
|
}
|
|
},
|
|
"offers": {
|
|
"@type": "Offer",
|
|
"url": "{{ app.request.schemeAndHttpHost }}{{ path('app_product_show',{'slug': (product.name|lower|replace({' ': '-'}))~"-"~product.id}) }}",
|
|
"priceCurrency": "EUR",
|
|
"price": "{{ product.price }}",
|
|
"itemCondition": "https://schema.org/{% if product.state == 'new' %}NewCondition{% else %}UsedCondition{% endif %}",
|
|
"availability": "https://schema.org/InStock",
|
|
"hasMerchantReturnPolicy": {
|
|
"@type": "MerchantReturnPolicy",
|
|
"applicableCountry": "FR",
|
|
"returnPolicyCategory": "https://schema.org/{% if product.custom %}MerchantReturnNotPermitted {% else %}MerchantReturnFiniteReturnWindow{% endif %}",
|
|
"merchantReturnDays": {% if product.custom %}0{%else%}14{% endif %},
|
|
"returnFees": "https://schema.org/{% if product.custom %}ReturnFeesCustomerResponsibility{%else%}ReturnFeesCustomerResponsibility{% endif %}",
|
|
"returnMethod": "https://schema.org/ReturnByMail"
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="container mx-auto p-4 md:p-8 pt-12">
|
|
<h1 class="text-4xl font-extrabold text-gray-900 mb-8 text-center">
|
|
{{ 'shop.welcome_title'|trans }}
|
|
</h1>
|
|
{# --- 2. CONTENU PRINCIPAL / AFFICHAGE DES PRODUITS --- #}
|
|
<main>
|
|
<p class="text-xl text-gray-600 mb-8 text-center">
|
|
{{ 'shop.description'|trans }}
|
|
</p>
|
|
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
|
|
{% for product in featuredProducts %}
|
|
<div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-xl transition duration-300 transform hover:-translate-y-1 border border-gray-100 relative">
|
|
|
|
{# ÉTIQUETTE PROMO (Absolute positioning) #}
|
|
{% if product.promo %}
|
|
<div class="absolute top-2 left-2 bg-red-600 text-white text-xs font-bold px-3 py-1 rounded-full shadow-lg z-10">
|
|
{{ 'shop.tag_promo'|trans }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# Image et Étiquette de Préférence (État) #}
|
|
<div class="relative">
|
|
<img src="{{ vich_uploader_asset(product,'image') | imagine_filter('webp')}}" alt="Image de {{ product.name }}" class="w-full h-48 object-cover">
|
|
|
|
{# Étiquette de préférence (Neuf/Occasion) #}
|
|
<div class="absolute bottom-0 right-0 bg-gray-900 text-white text-xs font-semibold px-2 py-1 rounded-tl-lg opacity-80">
|
|
{{ ('shop.state_' ~ product.state)|trans }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-4">
|
|
{# NOM #}
|
|
<h3 class="text-xl font-bold text-gray-900 mb-2 truncate">
|
|
{{ product.name }}
|
|
</h3>
|
|
|
|
{# TAGS SUPPLÉMENTAIRES #}
|
|
<div class="flex gap-2 mb-3 flex-wrap">
|
|
{% if product.handmade %}
|
|
<span class="text-xs font-medium bg-green-100 text-green-800 px-2 py-0.5 rounded-full">
|
|
{{ 'shop.tag_handmade'|trans }}
|
|
</span>
|
|
{% endif %}
|
|
{# Exemple de tag "Sur-mesure" basé sur une condition #}
|
|
{% if product.id == 1 %}
|
|
<span class="text-xs font-medium bg-blue-100 text-blue-800 px-2 py-0.5 rounded-full">
|
|
{{ 'shop.tag_custom'|trans }}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{# DESCRIPTION COURTE #}
|
|
<p class="text-sm text-gray-600 mb-4 line-clamp-2" title="{{ product.shortDescription }}">
|
|
{{ product.shortDescription }}
|
|
</p>
|
|
|
|
{# PRIX TTC et Bouton #}
|
|
<div class="flex justify-between items-center pt-3 border-t border-gray-100">
|
|
<span class="text-2xl font-extrabold text-indigo-600">
|
|
{{ product.price | number_format(2, ',', ' ') }} € TTC
|
|
</span>
|
|
<a href="{{ path('app_product_show', {'slug': (product.name|lower|replace({' ': '-'}))~"-"~product.id}) }}" class="text-indigo-600 hover:text-indigo-800 text-sm font-semibold inline-flex items-center group">
|
|
En savoir plus
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right ml-1 group-hover:translate-x-0.5 transition-transform"><path d="m9 18l6-6-6-6"/></svg>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
|
|
</main>
|
|
</div>
|
|
{% endblock %}
|