Files
ludikevent_crm/templates/dashboard/products/add.twig

262 lines
20 KiB
Twig
Raw Normal View History

{% extends 'dashboard/base.twig' %}
{% block title %}Fiche Produit{% endblock %}
{% block title_header %}Gestion du <span class="text-blue-500">Matériel</span>{% endblock %}
{% block actions %}
<div class="flex items-center gap-4">
<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
<svg class="w-3 h-3 ml-2 text-slate-500 group-hover:translate-x-1 group-hover:-translate-y-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<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>
</div>
{% 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 #}
{# SECTION IMAGE #}
<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>
Image du Produit
</h3>
<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>
</div>
</div>
<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'
}
}) }}
</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>
{# À 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>
</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>
{# 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>
<hr class="mt-2"/>
{# 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 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>
</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) }}
{# 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>
{{ form_label(formDoc.name, 'Nom du document', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
{{ 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>
{{ form_label(formDoc.isPublic, 'Visibilité Client', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] ml-1 mb-2 block'}}) }}
{{ 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">
{{ form_label(formDoc.docProduct, 'Fichier PDF (Notice, Certificat...)', {'label_attr': {'class': 'text-[10px] font-black text-slate-500 uppercase tracking-widest mb-4 block text-center'}}) }}
{{ 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 %}
</div>
{% endblock %}