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 %}
2026-01-22 15:58:57 +01:00
{% block actions %}
<div class="flex items-center gap-4">
2026-01-27 10:01:13 +01:00
{% if product .slug != "" %}
2026-01-22 15:58:57 +01:00
<a target="_blank" rel="nofollow"
href="https://reservation.ludikevent.fr {{ path ( 'reservation_product_show' , { id : product .slug } ) }} "
class="flex items-center px-6 py-3 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-blue-500/50 text-white text-[10px] font-black uppercase tracking-[0.2em] rounded-2xl transition-all group shadow-xl backdrop-blur-md">
<svg class="w-4 h-4 mr-2.5 text-blue-500 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
</svg>
Voir sur le site
2026-01-29 18:20:22 +01:00
<svg class="w-3 h-3 ml-2 text-slate-300 group-hover:translate-x-1 group-hover:-translate-y-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2026-01-22 15:58:57 +01:00
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
</a>
2026-01-27 10:01:13 +01:00
{% endif %}
2026-01-22 15:58:57 +01:00
</div>
{% endblock %}
2026-01-16 14:10:26 +01:00
{% 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">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .imageFile , 'Sélectionner un fichier' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-widest mb-2 block' }} ) }}
2026-01-16 14:23:53 +01:00
{# 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">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .name , 'Désignation Commerciale' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
{{ 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>
2026-01-29 18:20:22 +01:00
{{ form_label ( form .category , 'Catégorie' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
{{ 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>
2026-01-29 18:20:22 +01:00
{{ form_label ( form .ref , 'Référence Interne (SKU)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
{{ 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">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .description , 'Description détaillée' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-21 14:38:16 +01:00
{{ form_widget ( form .description , {
'attr': {
2026-01-28 10:30:47 +01:00
'is':'crm-editor',
2026-01-21 14:38:16 +01:00
'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>
2026-01-27 09:08:14 +01:00
{# 02. DIMENSIONS DU PRODUIT #}
<div class="mt-8 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">02</span>
Dimensions de la Structure
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
{# Largeur #}
<div class="relative group">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .dimW , 'Largeur (m)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-27 09:08:14 +01:00
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span class="text-slate-500 text-[10px] font-bold italic">W</span>
</div>
{{ form_widget ( form .dimW , { 'attr' : { 'placeholder' : '0.00' , '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 pl-10 pr-5' }} ) }}
</div>
</div>
{# Longueur #}
<div class="relative group">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .dimP , 'Longueur (m)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-27 09:08:14 +01:00
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span class="text-slate-500 text-[10px] font-bold italic">L</span>
</div>
{{ form_widget ( form .dimP , { 'attr' : { 'placeholder' : '0.00' , '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 pl-10 pr-5' }} ) }}
</div>
</div>
{# Hauteur #}
<div class="relative group">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .dimH , 'Hauteur (m)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-27 09:08:14 +01:00
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span class="text-slate-500 text-[10px] font-bold italic">H</span>
</div>
{{ form_widget ( form .dimH , { 'attr' : { 'placeholder' : '0.00' , '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 pl-10 pr-5' }} ) }}
</div>
</div>
</div>
</div>
2026-01-16 14:10:26 +01:00
</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>
{# PRIX LOCATION #}
<div class="space-y-6">
<div>
2026-01-29 18:20:22 +01:00
{{ form_label ( form .priceDay , 'Tarif 1er Jour (€) Ou Tarif weekend (si Barnums)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-widest ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
<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>
2026-01-29 18:20:22 +01:00
{{ form_label ( form .priceSup , 'Tarif Jour Sup. (€)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-widest ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
<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>
2026-01-27 08:46:12 +01:00
<hr class="mt-2"/>
2026-01-16 14:10:26 +01:00
{# CAUTION #}
<div class="pt-8 border-t border-white/5">
2026-01-29 18:20:22 +01:00
{{ form_label ( form .caution , 'Montant de la Caution (€)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-widest ml-1 mb-2 block' }} ) }}
2026-01-16 14:10:26 +01:00
<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>
2026-01-27 08:46:12 +01:00
<div class="mt-4 p-4 rounded-2xl bg-white/5 border border-white/10 backdrop-blur-md shadow-xl">
<div class="flex gap-3">
<div class="flex-shrink-0">
<svg class="w-5 h-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<p class="text-[11px] leading-relaxed text-slate-300">
<strong class="text-white block mb-1 uppercase tracking-wider">Information importante</strong>
Cette somme sera prélevée sur le compte bancaire du client. Conformément aux politiques de <span class="text-blue-400">Stripe</span>, les fonds peuvent être bloqués pour un maximum de <span class="font-bold text-white">4 jours</span>. Passé ce délai, aucun prélèvement ultérieur ne sera possible.
</p>
</div>
</div>
2026-01-16 14:10:26 +01:00
</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">
<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 ) }}
2026-01-22 15:58:57 +01:00
{# 03. DOCUMENTS TECHNIQUES (PDF) #}
{% if formDoc is defined %}
<div class="backdrop-blur-xl bg-[#1e293b]/40 border border-white/5 rounded-[2.5rem] p-8 shadow-2xl mt-8">
<h3 class="text-lg font-bold text-white mb-6 flex items-center">
<span class="w-8 h-8 bg-amber-600/20 text-amber-500 rounded-lg flex items-center justify-center mr-3 text-[10px] font-black">03</span>
Documents & Notices
</h3>
{# LISTE DES DOCUMENTS EXISTANTS #}
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-10">
{% for doc in product .productDocs %}
<div class="flex items-center justify-between p-4 bg-white/5 border border-white/5 rounded-2xl group hover:bg-white/10 transition-all">
<div class="flex items-center">
<div class="w-10 h-10 bg-red-500/20 text-red-500 rounded-xl flex items-center justify-center mr-4">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
</div>
<div>
<div class="text-xs font-black text-white uppercase tracking-wider"> {{ doc .name }} </div>
<div class="text-[9px] font-bold {{ doc .isPublic ? 'text-emerald-500' : 'text-slate-500' }} uppercase tracking-tighter">
{{ doc .isPublic ? '● Public' : '○ Privé (Interne)' }}
</div>
</div>
</div>
<div class="flex gap-2">
<a href=" {{ vich_uploader_asset ( doc , 'docProduct' ) }} " target="_blank" class="p-2 text-slate-400 hover:text-white transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
</a>
<form data-turbo="false" method="post" action=" {{ path ( 'app_crm_product_edit' , { 'id' : product .id , act :'deleted' , idDoc : doc .id } ) }} "
onsubmit="return confirm('Confirmer la suppression de ce document ?');"
class="inline-block">
<input type="hidden" name="_token" value=" {{ csrf_token ( 'delete' ~ doc .id ) }} ">
<button type="submit" class="p-2 text-slate-400 hover:text-rose-500 transition-colors" title="Supprimer">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
</form>
{# Ici tu pourrais ajouter un lien de suppression #}
</div>
</div>
{% else %}
<div class="md:col-span-2 py-8 text-center border-2 border-dashed border-white/5 rounded-3xl">
<p class="text-[10px] font-black text-slate-600 uppercase tracking-[0.2em]">Aucun document attaché</p>
</div>
{% endfor %}
</div>
<div class="h-px bg-white/5 w-full mb-10"></div>
{# FORMULAIRE D'AJOUT #}
{{ form_start ( formDoc ) }}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 items-end">
<div>
2026-01-29 18:20:22 +01:00
{{ form_label ( formDoc .name , 'Nom du document' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-22 15:58:57 +01:00
{{ form_widget ( formDoc .name , { 'attr' : { 'placeholder' : 'Ex: Notice technique PDF' , 'class' : 'w-full bg-slate-900/50 border-white/5 rounded-2xl text-white focus:ring-amber-500/20 focus:border-amber-500 transition-all py-4 px-5 font-bold text-sm' }} ) }}
</div>
<div>
2026-01-29 18:20:22 +01:00
{{ form_label ( formDoc .isPublic , 'Visibilité Client' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-[0.2em] ml-1 mb-2 block' }} ) }}
2026-01-22 15:58:57 +01:00
{{ form_widget ( formDoc .isPublic , { '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-4 px-5 font-bold text-sm cursor-pointer' }} ) }}
</div>
<div class="md:col-span-2 bg-slate-950/40 p-6 rounded-[2rem] border border-dashed border-white/10 group hover:border-amber-500/30 transition-all">
2026-01-29 18:20:22 +01:00
{{ form_label ( formDoc .docProduct , 'Fichier PDF (Notice, Certificat...)' , { 'label_attr' : { 'class' : 'text-[10px] font-black text-slate-300 uppercase tracking-widest mb-4 block text-center' }} ) }}
2026-01-22 15:58:57 +01:00
{{ form_widget ( formDoc .docProduct , {
'attr': {
'class': 'block w-full text-xs text-slate-400 file:mr-4 file:py-3 file:px-6 file:rounded-xl file:border-0 file:text-[10px] file:font-black file:uppercase file:tracking-widest file:bg-amber-600 file:text-white hover:file:bg-amber-500 transition-all cursor-pointer'
}
}) }}
</div>
</div>
<div class="mt-8 flex justify-end">
<button type="submit" class="group px-8 py-4 bg-amber-600/10 hover:bg-amber-600 text-amber-500 hover:text-white text-[10px] font-black uppercase tracking-widest rounded-2xl transition-all border border-amber-500/20 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="M12 4v16m8-8H4"/></svg>
Ajouter au dossier
</button>
</div>
{{ form_end ( formDoc ) }}
</div>
{% endif %}
2026-01-16 14:10:26 +01:00
</div>
{% endblock %}