Files
ludikevent_crm/templates/reservation/contrat/gestion_contrat/contrats.twig
Serreau Jovann 7ff3538bcd ```
 feat(contrats): Améliore la gestion des contrats et des paiements.

- Rend le champ details non obligatoire dans add.twig
- Ajoute une valeur par défaut pour isSigned et type dans les entités.
- Corrige l'ajout des lignes et options au contrat.
- Ajoute la création automatique du client Stripe.
```
2026-02-06 11:06:38 +01:00

131 lines
9.6 KiB
Twig

<div class="space-y-8 animate-fade-in">
{# --- EN-TÊTE --- #}
<div class="border-b border-gray-100 pb-6 flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<h2 class="text-2xl font-bold text-gray-900">Mes Réservations</h2>
<p class="text-sm text-gray-500">Suivez l'avancement de vos contrats et l'état de vos règlements.</p>
</div>
<div class="bg-blue-600 text-white px-5 py-2 rounded-2xl text-xs font-bold uppercase tracking-wider shadow-lg shadow-blue-100">
{{ customer.contrats|length }} Contrat(s) actif(s)
</div>
</div>
{# --- LISTE DES CONTRATS --- #}
<div class="grid grid-cols-1 gap-6">
{% for contrat in customer.contrats %}
<div class="bg-white rounded-[2.5rem] border border-gray-100 p-6 md:p-8 shadow-sm hover:shadow-xl transition-all duration-300 group">
<div class="flex flex-col lg:flex-row gap-8">
{# COLONNE 1 : IDENTIFICATION ET LIEU #}
<div class="lg:w-1/3 space-y-4">
<div class="flex items-center gap-4">
<div class="bg-gray-900 text-white p-3.5 rounded-2xl shadow-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
</div>
<div>
<p class="text-[10px] font-bold text-gray-400 uppercase tracking-widest">Référence Contrat</p>
<h3 class="text-xl font-black text-gray-900 tracking-tight">#{{ contrat.numReservation }}</h3>
</div>
</div>
<div class="bg-gray-50 rounded-2xl p-4 border border-gray-100">
<div class="flex items-center gap-2 mb-2 text-gray-400">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" /></svg>
<p class="text-[10px] font-bold uppercase tracking-widest">Lieu de l'événement</p>
</div>
<p class="text-sm font-bold text-gray-800 leading-snug">
{{ contrat.adressEvent }}<br>
{% if contrat.adress2Event %}{{ contrat.adress2Event }}<br>{% endif %}
{{ contrat.zipCodeEvent }} {{ contrat.townEvent|upper }}
</p>
</div>
</div>
{# COLONNE 2 : FINANCES ET ÉTAT DES PAIEMENTS #}
<div class="lg:w-2/3 flex flex-col justify-between">
{# Chiffres clés #}
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8">
<div class="p-4 bg-blue-50/50 rounded-2xl border border-blue-100/50">
<p class="text-[10px] font-bold text-blue-400 uppercase mb-1 tracking-tighter">Total Contrat</p>
<p class="text-lg font-black text-blue-700">{{ contrat|totalContrat }} €</p>
</div>
<div class="p-4 bg-orange-50/50 rounded-2xl border border-orange-100/50">
<p class="text-[10px] font-bold text-orange-400 uppercase mb-1 tracking-tighter">Arrhes (25%)</p>
<p class="text-lg font-black text-orange-700">{{ (contrat|totalContrat * 0.25)|number_format(2, ',', ' ') }} €</p>
</div>
<div class="p-4 bg-green-50/50 rounded-2xl border border-green-100/50">
<p class="text-[10px] font-bold text-green-400 uppercase mb-1 tracking-tighter">Déjà versé</p>
<p class="text-lg font-black text-green-700">{{ contrat|totalContratAccompte }} €</p>
</div>
</div>
{# Badges de Statuts (Paiements) #}
<div class="flex flex-wrap items-center gap-3">
<div class="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-xl border border-gray-100">
<span class="text-[10px] font-bold text-gray-400 uppercase">Signée</span>
{% if contrat.isSigned %}
<span class="flex items-center gap-1 text-[10px] font-black text-green-600 bg-green-100 px-2 py-0.5 rounded-lg uppercase">
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" /></svg>
Signée
</span>
{% else %}
<span class="text-[10px] font-black text-orange-500 bg-orange-100 px-2 py-0.5 rounded-lg uppercase">Non signée</span>
{% endif %}
</div>
{# ACOMPTE #}
<div class="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-xl border border-gray-100">
<span class="text-[10px] font-bold text-gray-400 uppercase">Acompte</span>
{% if contratPaymentPay(contrat, 'accompte') %}
<span class="flex items-center gap-1 text-[10px] font-black text-green-600 bg-green-100 px-2 py-0.5 rounded-lg uppercase">
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" /></svg>
Réglé
</span>
{% else %}
<span class="text-[10px] font-black text-orange-500 bg-orange-100 px-2 py-0.5 rounded-lg uppercase">À payer</span>
{% endif %}
</div>
{# SOLDE #}
<div class="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-xl border border-gray-100">
<span class="text-[10px] font-bold text-gray-400 uppercase">Solde</span>
{% if contratPaymentPay(contrat, 'solde') %}
<span class="text-[10px] font-black text-green-600 bg-green-100 px-2 py-0.5 rounded-lg uppercase">Payé</span>
{% else %}
<span class="text-[10px] font-black text-gray-400 bg-gray-200 px-2 py-0.5 rounded-lg uppercase">Attente</span>
{% endif %}
</div>
{# BOUTON ACTION #}
<div class="ml-auto pt-4 md:pt-0 w-full md:w-auto">
<a href="{{ path('gestion_contrat_view', {num: contrat.numReservation}) }}"
class="flex items-center justify-center gap-3 bg-gray-900 text-white px-8 py-3.5 rounded-2xl font-bold text-sm hover:bg-blue-600 transition-all shadow-xl shadow-gray-200 active:scale-95 group-hover:bg-blue-600">
Voir les détails
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
</a>
</div>
</div>
</div>
</div>
</div>
{% else %}
{# --- ÉTAT VIDE --- #}
<div class="py-24 text-center bg-white rounded-[3rem] border-2 border-dashed border-gray-100">
<div class="mb-4 inline-block p-4 bg-gray-50 rounded-full text-gray-300">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg>
</div>
<p class="text-gray-400 font-medium">Vous n'avez aucun contrat actif pour le moment.</p>
<a href="{{ path('reservation') }}" class="mt-4 inline-block text-blue-600 font-bold hover:underline">Effectuer une nouvelle réservation</a>
</div>
{% endfor %}
</div>
</div>