2026-01-16 14:10:26 +01:00
|
|
|
{% extends 'dashboard/base.twig' %}
|
|
|
|
|
|
|
|
|
|
{% block title %}Fiche Produit{% endblock %}
|
|
|
|
|
{% block title_header %}Gestion du <span class="text-blue-500">Matériel</span>{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block body %}
|
|
|
|
|
<div class="max-w-6xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-700">
|
|
|
|
|
{{ form_start(form) }}
|
|
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
|
|
|
|
|
|
|
|
{# COLONNE GAUCHE : VISUEL & IDENTITÉ #}
|
|
|
|
|
<div class="lg:col-span-2 space-y-8">
|
|
|
|
|
|
|
|
|
|
{# 00. IMAGE DU PRODUIT #}
|
2026-01-16 14:23:53 +01:00
|
|
|
{# SECTION IMAGE #}
|
2026-01-16 14:10:26 +01:00
|
|
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] p-8 shadow-2xl">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-6 flex items-center">
|
|
|
|
|
<span class="w-8 h-8 bg-purple-600/20 text-purple-500 rounded-lg flex items-center justify-center mr-3 text-[10px] font-black">00</span>
|
2026-01-16 14:23:53 +01:00
|
|
|
Image du Produit
|
2026-01-16 14:10:26 +01:00
|
|
|
</h3>
|
|
|
|
|
|
2026-01-16 14:23:53 +01:00
|
|
|
<div class="flex flex-col md:flex-row items-center gap-8">
|
|
|
|
|
<div class="relative flex-shrink-0">
|
|
|
|
|
<div class="w-48 h-48 rounded-[2rem] overflow-hidden border-2 border-white/10 bg-slate-900/50 flex items-center justify-center">
|
|
|
|
|
{# L'image avec un ID spécifique pour le JS #}
|
|
|
|
|
<img id="product-image-preview"
|
|
|
|
|
src="{{ product.imageName ? vich_uploader_asset(product, 'imageFile') | imagine_filter('webp') : '#' }}"
|
|
|
|
|
class="w-full h-full object-cover {{ product.imageName ? '' : 'hidden' }}">
|
|
|
|
|
|
|
|
|
|
{# L'icône de remplacement #}
|
|
|
|
|
<svg id="product-image-placeholder"
|
|
|
|
|
class="w-12 h-12 text-slate-700 {{ product.imageName ? 'hidden' : '' }}"
|
|
|
|
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
|
|
|
</svg>
|
2026-01-16 14:10:26 +01:00
|
|
|
</div>
|
2026-01-16 14:23:53 +01:00
|
|
|
</div>
|
2026-01-16 14:10:26 +01:00
|
|
|
|
2026-01-16 14:23:53 +01:00
|
|
|
<div class="flex-1 w-full">
|
|
|
|
|
{{ form_label(form.imageFile, 'Sélectionner un fichier', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-widest mb-2 block'}}) }}
|
|
|
|
|
|
|
|
|
|
{# On enlève le "onchange" inline, on cible via l'ID généré par Symfony ou un ID fixe #}
|
|
|
|
|
{{ form_widget(form.imageFile, {
|
|
|
|
|
'id': 'product_image_input',
|
|
|
|
|
'attr': {
|
|
|
|
|
'class': 'block w-full text-xs text-slate-400 file:mr-4 file:py-2.5 file:px-4 file:rounded-xl file:border-0 file:text-[10px] file:font-black file:uppercase file:tracking-widest file:bg-blue-600/10 file:text-blue-500 hover:file:bg-blue-600/20 transition-all cursor-pointer'
|
|
|
|
|
}
|
|
|
|
|
}) }}
|
2026-01-16 14:10:26 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{# 01. INFORMATIONS GÉNÉRALES #}
|
|
|
|
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] p-8 shadow-2xl">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-6 flex items-center">
|
|
|
|
|
<span class="w-8 h-8 bg-blue-600/20 text-blue-500 rounded-lg flex items-center justify-center mr-3 text-[10px] font-black">01</span>
|
|
|
|
|
Détails du Catalogue
|
|
|
|
|
</h3>
|
|
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
|
|
|
<div class="md:col-span-2">
|
|
|
|
|
{{ form_label(form.name, 'Désignation Commerciale', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
|
|
|
|
|
{{ form_widget(form.name, {'attr': {'placeholder': 'Ex: Château Gonflable Jungle', 'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
{{ form_label(form.category, 'Catégorie', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
|
|
|
|
|
{{ form_widget(form.category, {'attr': {'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
{{ form_label(form.ref, 'Référence Interne (SKU)', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
|
|
|
|
|
{{ form_widget(form.ref, {'attr': {'placeholder': 'REF-000', 'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white font-mono focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5'}}) }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-21 14:38:16 +01:00
|
|
|
{# À placer juste après le bloc Référence Interne #}
|
|
|
|
|
<div class="md:col-span-2 mt-6">
|
|
|
|
|
{{ form_label(form.description, 'Description détaillée', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
|
|
|
|
|
{{ form_widget(form.description, {
|
|
|
|
|
'attr': {
|
|
|
|
|
'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3.5 px-5 min-h-[150px]',
|
|
|
|
|
'placeholder': 'Décrivez les dimensions, la capacité, les points forts...'
|
|
|
|
|
}
|
|
|
|
|
}) }}
|
|
|
|
|
{% if form_errors(form.description) %}
|
|
|
|
|
<div class="text-rose-500 text-[10px] font-bold mt-2 ml-2 uppercase tracking-widest">
|
|
|
|
|
{{ form_errors(form.description) }}
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
2026-01-16 14:10:26 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# COLONNE DROITE : TARIFICATION #}
|
|
|
|
|
<div class="lg:col-span-1 space-y-8">
|
|
|
|
|
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] p-8 shadow-2xl h-full border-l-emerald-500/10 border-l-2">
|
|
|
|
|
<h3 class="text-lg font-bold text-white mb-8 flex items-center">
|
|
|
|
|
<span class="w-8 h-8 bg-emerald-600/20 text-emerald-500 rounded-lg flex items-center justify-center mr-3 text-[10px] font-black">02</span>
|
|
|
|
|
Finances & Tarifs
|
|
|
|
|
</h3>
|
|
|
|
|
|
|
|
|
|
<div class="space-y-8">
|
|
|
|
|
{# INSTALLATION (Montant) #}
|
|
|
|
|
<div class="p-5 bg-white/5 rounded-3xl border border-white/5 relative overflow-hidden group">
|
|
|
|
|
<div class="absolute top-0 right-0 p-2 opacity-10">
|
|
|
|
|
<svg class="w-12 h-12 text-white" 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" /></svg>
|
|
|
|
|
</div>
|
|
|
|
|
{{ form_label(form.installation, 'Forfait Installation (€)', {'label_attr': {'class': 'text-[9px] font-black text-amber-500 uppercase tracking-widest mb-3 block'}}) }}
|
|
|
|
|
{{ form_widget(form.installation, {'attr': {'class': 'w-full bg-slate-950/50 border-white/10 rounded-xl text-amber-500 font-bold focus:ring-amber-500/20 focus:border-amber-500 transition-all py-3 px-4 text-lg'}}) }}
|
|
|
|
|
<p class="text-[8px] text-slate-500 mt-2 font-bold uppercase italic tracking-tighter">Saisir 0 si inclus dans la loc</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# PRIX LOCATION #}
|
|
|
|
|
<div class="space-y-6">
|
|
|
|
|
<div>
|
|
|
|
|
{{ form_label(form.priceDay, 'Tarif 1er Jour (€)', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1 mb-2 block'}}) }}
|
|
|
|
|
<div class="relative">
|
|
|
|
|
{{ form_widget(form.priceDay, {'attr': {'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-emerald-400 font-black text-xl focus:ring-emerald-500/20 focus:border-emerald-500 transition-all py-4 px-5'}}) }}
|
|
|
|
|
<span class="absolute right-5 top-1/2 -translate-y-1/2 text-slate-600 font-bold">€HT</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
{{ form_label(form.priceSup, 'Tarif Jour Sup. (€)', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1 mb-2 block'}}) }}
|
|
|
|
|
<div class="relative">
|
|
|
|
|
{{ form_widget(form.priceSup, {'attr': {'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-blue-400 font-black text-xl focus:ring-blue-500/20 focus:border-blue-500 transition-all py-4 px-5'}}) }}
|
|
|
|
|
<span class="absolute right-5 top-1/2 -translate-y-1/2 text-slate-600 font-bold">€HT</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# CAUTION #}
|
|
|
|
|
<div class="pt-8 border-t border-white/5">
|
|
|
|
|
{{ form_label(form.caution, 'Montant de la Caution (€)', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-widest ml-1 mb-2 block'}}) }}
|
|
|
|
|
<div class="relative">
|
|
|
|
|
{{ form_widget(form.caution, {'attr': {'class': 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white font-mono focus:ring-blue-500/20 focus:border-blue-500 transition-all py-3 px-5 text-center'}}) }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# FOOTER ACTIONS #}
|
|
|
|
|
<div class="mt-12 mb-20 flex items-center justify-between backdrop-blur-xl bg-slate-900/40 p-6 rounded-[2rem] border border-white/5 shadow-xl">
|
|
|
|
|
<a href="{{ path('app_crm_product') }}" class="px-8 py-3 text-[10px] font-black text-slate-400 hover:text-white uppercase tracking-widest transition-colors flex items-center group">
|
|
|
|
|
<svg class="w-4 h-4 mr-2 transform 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="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
|
|
|
|
|
Retour au catalogue
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
<button type="submit" class="relative overflow-hidden group px-12 py-4 bg-blue-600 hover:bg-blue-500 text-white text-[10px] font-black uppercase tracking-[0.2em] rounded-2xl transition-all shadow-lg shadow-blue-600/30">
|
|
|
|
|
<span class="relative z-10 flex items-center">
|
|
|
|
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7" /></svg>
|
|
|
|
|
Enregistrer la fiche
|
|
|
|
|
</span>
|
|
|
|
|
<div class="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000"></div>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{{ form_end(form) }}
|
|
|
|
|
</div>
|
|
|
|
|
{% endblock %}
|