✨ feat(reservation/flow): Améliore le flux de réservation et ajoute des options.
Cette commit améliore le flux de réservation, ajoute une estimation des
frais de livraison et gère les options de produit et les paiements.
```
381 lines
30 KiB
Twig
381 lines
30 KiB
Twig
{% extends 'revervation/base.twig' %}
|
|
|
|
{% block title %}Récapitulatif de réservation #{{ contrat.numReservation }}{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="min-h-screen bg-slate-50 py-12 px-4">
|
|
<div class="max-w-7xl mx-auto">
|
|
|
|
{# HEADER : NAVIGATION, TITRE, DATES & LIEU #}
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
|
|
<div class="md:col-span-2 flex items-center gap-6">
|
|
<a href="{{ path('gestion_contrat') }}" class="w-12 h-12 bg-white rounded-2xl border border-slate-100 flex items-center justify-center text-slate-400 hover:text-blue-600 transition-all shadow-sm">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
|
|
</a>
|
|
<div class="flex flex-col md:flex-row md:items-center gap-4 md:gap-8">
|
|
<div>
|
|
<h1 class="text-3xl font-black italic uppercase text-slate-900 leading-none">Détails <span class="text-blue-600">Réservation</span></h1>
|
|
<p class="text-slate-400 text-[10px] font-black uppercase tracking-[0.2em] mt-2">Référence : #{{ contrat.numReservation }}</p>
|
|
</div>
|
|
|
|
<div class="flex items-center bg-white px-6 py-3 rounded-2xl border border-slate-100 shadow-sm gap-6">
|
|
<div class="text-center">
|
|
<p class="text-[8px] font-black uppercase text-slate-400 tracking-widest mb-1">Du</p>
|
|
<p class="text-sm font-black text-slate-900 uppercase italic">{{ contrat.dateAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
<div class="flex flex-col items-center">
|
|
<div class="h-px w-8 bg-blue-200 mb-1"></div>
|
|
<span class="text-[9px] font-black text-blue-600 uppercase">{{ days }} J</span>
|
|
</div>
|
|
<div class="text-center">
|
|
<p class="text-[8px] font-black uppercase text-slate-400 tracking-widest mb-1">Au</p>
|
|
<p class="text-sm font-black text-slate-900 uppercase italic">{{ contrat.endAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-blue-600 rounded-[2rem] p-5 text-white flex items-center gap-4 shadow-lg shadow-blue-200">
|
|
<div class="w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center shrink-0">
|
|
<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="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>
|
|
</div>
|
|
<div class="overflow-hidden">
|
|
<p class="text-[9px] font-black uppercase tracking-widest opacity-80 mb-1">Lieu de l'événement</p>
|
|
<p class="font-bold uppercase italic text-[11px] truncate leading-tight">
|
|
{{ contrat.addressEvent }} {% if contrat.address2Event %}- {{ contrat.address2Event }}{% endif %}
|
|
</p>
|
|
<p class="font-black uppercase italic text-sm truncate">{{ contrat.townEvent }} ({{ contrat.zipCodeEvent }})</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# SECTION IDENTITÉ #}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
|
|
<div class="bg-white rounded-[2.5rem] p-8 border border-slate-100 shadow-sm">
|
|
<p class="text-[10px] font-black text-blue-600 uppercase tracking-widest mb-4">Le Prestataire</p>
|
|
<p class="text-xl font-black text-slate-900 uppercase italic">SEGARD LILIAN - <span class="text-blue-600">LUDIKEVENT</span></p>
|
|
<div class="mt-4 space-y-1 text-sm text-slate-500 font-medium italic">
|
|
<p>6, rue du Château, 02800 DANIZY</p>
|
|
<p>SIRET : 930 488 408 00012</p>
|
|
<p class="text-blue-600 font-black not-italic mt-2">06 14 17 24 47</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-[2.5rem] p-8 border border-slate-100 shadow-sm">
|
|
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest mb-4">Le Client / Loueur</p>
|
|
<p class="text-xl font-black text-slate-900 uppercase italic">{{ contrat.customer.name }} {{ contrat.customer.surname }}</p>
|
|
<div class="mt-4 space-y-2">
|
|
<div class="flex items-center gap-2">
|
|
<svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
|
<p class="text-sm text-slate-900 font-bold underline decoration-blue-200 underline-offset-4">{{ contrat.customer.email }}</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/></svg>
|
|
<p class="text-sm text-slate-900 font-bold underline decoration-blue-200 underline-offset-4">{{ contrat.customer.phone }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-8 items-start mb-12">
|
|
{# COLONNE GAUCHE : PRESTATIONS ET DOCS #}
|
|
<div class="lg:col-span-3 space-y-6">
|
|
<div class="bg-white rounded-[2.5rem] border border-slate-100 shadow-xl shadow-slate-200/40 overflow-hidden">
|
|
<div class="p-8 border-b border-slate-50 flex justify-between items-center bg-slate-50/30">
|
|
<h2 class="text-xs font-black uppercase tracking-widest text-slate-900">Détail des prestations & Options</h2>
|
|
<span class="bg-blue-600 text-white text-[10px] font-black px-4 py-1.5 rounded-full uppercase">{{ days }} Jours</span>
|
|
</div>
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left">
|
|
<tbody class="divide-y divide-slate-50">
|
|
{% for line in contrat.contratsLines %}
|
|
{% if tvaEnabled %}
|
|
{% set priceLine = (line.price1DayHt*1.20) + ((line.priceSupDayHt*1.20) * (days - 1)) %}
|
|
{% else %}
|
|
{% set priceLine = line.price1DayHt + (line.priceSupDayHt * (days - 1)) %}
|
|
{% endif %}
|
|
<tr class="hover:bg-slate-50/30 transition-colors">
|
|
<td class="px-8 py-6">
|
|
<p class="font-black text-slate-900 uppercase text-sm leading-tight">{{ line.name }}</p>
|
|
{% if tvaEnabled %}
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix 1 Jour : {{ (line.price1DayHt*1.20)|number_format(0, ',', ' ') }}€ TTC</p>
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix Jour suplémentaire : {{ (line.priceSupDayHt*1.20)|number_format(0, ',', ' ') }}€ TTC</p>
|
|
{% else %}
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix 1 Jour : {{ line.price1DayHt|number_format(0, ',', ' ') }}€ HT</p>
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix Jour suplémentaire : {{ line.priceSupDayHt|number_format(0, ',', ' ') }}€ HT</p>
|
|
{% endif %}
|
|
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Caution : {{ line.caution|number_format(0, ',', ' ') }}€</p>
|
|
</td>
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ priceLine|number_format(2, ',', ' ') }}€</td>
|
|
|
|
</tr>
|
|
{% endfor %}
|
|
{% for line in contrat.contratsOptions %}
|
|
<tr class="bg-slate-50/20">
|
|
<td class="px-8 py-6">
|
|
<p class="font-bold text-blue-600 uppercase text-xs italic tracking-widest mb-1">Option</p>
|
|
<p class="font-black text-slate-900 uppercase text-sm leading-tight">{{ line.name }}</p>
|
|
</td>
|
|
{% if tvaEnabled %}
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ (line.price*1.20)|number_format(2, ',', ' ') }}€</td>
|
|
{% else %}
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ line.price|number_format(2, ',', ' ') }}€</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{# DOCUMENTS PDF #}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{% set contractPath = contrat.signed ? 'devisSignFile' : 'devisFile' %}
|
|
<a download href="{{ vich_uploader_asset(contrat, contractPath) }}" class="group flex items-center justify-between p-3 pr-8 bg-white border border-slate-100 rounded-3xl shadow-sm hover:border-blue-200 transition-all">
|
|
<div class="w-14 h-14 bg-blue-50 rounded-2xl flex items-center justify-center text-blue-600 shrink-0 group-hover:bg-blue-600 group-hover:text-white transition-all">
|
|
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 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"></path></svg>
|
|
</div>
|
|
<span class="text-xs font-black uppercase tracking-widest text-slate-600 italic">Contrat (PDF)</span>
|
|
</a>
|
|
{% if contrat.signed %}
|
|
<a download href="{{ vich_uploader_asset(contrat, 'devisAuditFile') }}" class="group flex items-center justify-between p-3 pr-8 bg-white border border-slate-100 rounded-3xl shadow-sm hover:border-blue-200 transition-all">
|
|
<div class="w-14 h-14 bg-blue-50 rounded-2xl flex items-center justify-center text-blue-600 shrink-0 group-hover:bg-blue-600 group-hover:text-white transition-all">
|
|
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path></svg>
|
|
</div>
|
|
<span class="text-xs font-black uppercase tracking-widest text-slate-600 italic">Certificat</span>
|
|
</a>
|
|
{% endif %}
|
|
{% if solde <=0 %}
|
|
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{# --- COLONNE DROITE : FINANCES --- #}
|
|
<div class="lg:col-span-2 space-y-4">
|
|
{# TOTAL HT - Version compacte #}
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Hors Taxes (HT)</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ totalHT|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
{% if tvaEnabled %}
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Total TVA</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ (totalTTC-totalHT)|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Total TTC</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ totalTTC|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
{% endif %}
|
|
{# SOLDE FINAL - Bloc Principal avec saisie du montant #}
|
|
<div class="bg-slate-900 rounded-[2rem] p-8 text-white shadow-xl shadow-slate-200 relative overflow-hidden">
|
|
<div class="absolute top-0 right-0 -mt-4 -mr-4 w-24 h-24 bg-blue-600/10 rounded-full blur-2xl"></div>
|
|
|
|
<div class="relative">
|
|
<p class="text-xs font-black text-blue-400 uppercase tracking-widest mb-2">Solde restant à régler</p>
|
|
<div class="flex items-baseline gap-2 mb-8">
|
|
<p class="text-5xl font-black italic tracking-tighter">{{ solde|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
|
|
{% set acompteOk = contratPaymentPay(contrat, 'accompte') %}
|
|
|
|
{% if solde <=0 %}
|
|
<div class="flex items-center gap-3 bg-green-500/20 text-green-400 p-6 rounded-2xl border border-green-500/30">
|
|
<svg class="w-8 h-8 shrink-0" 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>
|
|
<div>
|
|
<p class="text-sm font-black uppercase italic">Dossier Soldé</p>
|
|
<p class="text-[9px] opacity-70 font-bold uppercase tracking-widest">Aucun montant restant</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<p class="text-[9px] text-slate-500 font-bold uppercase italic mt-6 text-center tracking-widest opacity-60">
|
|
Paiement sécurisé via Stripe
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# --- SECTION ACTIONS : 3 COLONNES --- #}
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
|
|
{# 1. SIGNATURE #}
|
|
{% if contrat.signed %}
|
|
<div class="bg-white rounded-[2rem] border border-green-100 shadow-xl shadow-green-100/20 overflow-hidden">
|
|
<div class="bg-green-500 p-6 text-white flex items-center gap-4">
|
|
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Contrat Signé</p>
|
|
</div>
|
|
<div class="p-6 text-center">
|
|
<p class="text-[10px] text-slate-400 font-black uppercase mb-1 tracking-widest">Numéro de signature</p>
|
|
<p class="text-[10px] font-mono font-bold text-slate-800 break-all bg-slate-50 p-3 rounded-xl border border-slate-100">{{ signedNumber }}</p>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-white rounded-[2rem] border border-red-100 shadow-xl shadow-red-100/20 overflow-hidden">
|
|
<div class="bg-red-500 p-6 text-white flex items-center gap-4">
|
|
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Signature</p>
|
|
</div>
|
|
<div class="p-6">
|
|
<a href="{{ signUrl }}" class="flex flex-col items-center justify-center p-5 bg-slate-900 text-white rounded-2xl hover:bg-blue-600 transition-all group shadow-lg">
|
|
<span class="font-black uppercase italic text-sm">Signer le contrat</span>
|
|
<span class="text-[9px] text-blue-300 font-black uppercase mt-1 tracking-widest">Étape 1 : Obligatoire</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# 2. ACOMPTE #}
|
|
{% if not contratPaymentPay(contrat, 'accompte') %}
|
|
<div class="bg-white rounded-[2rem] border border-red-100 shadow-xl shadow-red-100/20 overflow-hidden">
|
|
<div class="bg-red-500 p-6 text-white flex items-center gap-4">
|
|
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Acompte (25%)</p>
|
|
</div>
|
|
<div class="p-6 text-center">
|
|
<p class="text-3xl font-black text-slate-900 italic mb-4">{{ arrhes|number_format(2, ',', ' ') }}€</p>
|
|
{% if contrat.signed %}
|
|
<a data-turbo="false" href="{{ path('gestion_contrat_view', {'num': contrat.numReservation,'act':'accomptePay'}) }}" class="block w-full bg-slate-900 text-white py-4 rounded-xl font-black uppercase text-xs hover:bg-blue-600 transition-all shadow-md">Régler l'acompte</a>
|
|
{% else %}
|
|
<div class="p-3 bg-amber-50 rounded-xl border border-amber-100">
|
|
<span class="text-[9px] text-amber-600 font-black uppercase tracking-tighter">Attente de signature du contrat</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-white rounded-[2rem] border border-green-100 shadow-xl shadow-green-100/20 overflow-hidden">
|
|
<div class="bg-green-500 p-6 text-white flex items-center gap-4">
|
|
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Acompte Réglé</p>
|
|
</div>
|
|
<div class="p-5">
|
|
{% for payment in paymentList %}
|
|
<div class="bg-slate-50 p-4 rounded-2xl border border-slate-100">
|
|
<div class="flex justify-between items-center mb-2">
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Moyen utilisé</p>
|
|
<p class="text-lg font-black text-slate-900 italic leading-none">{{ payment.amount|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-[10px] font-black uppercase text-slate-700 italic">{{ payment.card.method_label|default('Carte Bancaire') }}</span>
|
|
{% if payment.card.type == "card" %}
|
|
<span class="text-[9px] text-slate-400 font-bold uppercase italic">({{ payment.card.card.brand|default('') }} **** {{ payment.card.card.last4|default('') }})</span>
|
|
{% endif %}
|
|
</div>
|
|
<p class="text-[8px] text-slate-400 font-medium italic mt-2 uppercase tracking-tighter">Validé le {{ payment.validateAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
</div>
|
|
{# ... (Garder tout le code précédent inchangé jusqu'à la fin de la grille 3 colonnes) ... #}
|
|
|
|
{# --- SECTION HISTORIQUE COMPLET DES TRANSACTIONS --- #}
|
|
<div class="mt-12">
|
|
<div class="flex items-center gap-4 mb-6">
|
|
<div class="h-px flex-1 bg-slate-200"></div>
|
|
<h2 class="text-[10px] font-black uppercase tracking-[0.3em] text-slate-400">Historique des transactions</h2>
|
|
<div class="h-px flex-1 bg-slate-200"></div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-[2.5rem] border border-slate-100 shadow-sm overflow-hidden">
|
|
<table class="w-full text-left">
|
|
<thead>
|
|
<tr class="bg-slate-50/50 border-b border-slate-100">
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Date & Heure</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Type / Objet</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Méthode</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-right">Montant</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-right">Confirmation de paiement</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-center">Statut</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50">
|
|
{# Fusion de toutes les listes de paiement pour l'affichage global #}
|
|
{% set allPayments = paymentList|merge(paymentCaution)|merge(paymentCtaList|default([])) %}
|
|
|
|
{% if allPayments is not empty %}
|
|
{% for pay in allPayments|sort((a, b) => b.validateAt <=> a.validateAt) %}
|
|
<tr class="hover:bg-slate-50/30 transition-colors">
|
|
<td class="px-8 py-5">
|
|
<p class="text-xs font-bold text-slate-900">{{ pay.validateAt|date('d/m/Y') }}</p>
|
|
<p class="text-[10px] text-slate-400 italic">{{ pay.validateAt|date('H:i') }}</p>
|
|
</td>
|
|
<td class="px-8 py-5">
|
|
{% if pay in paymentCaution %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-slate-100 text-slate-600 tracking-tighter">Caution (Empreinte)</span>
|
|
{% elseif pay in paymentList %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-blue-50 text-blue-600 tracking-tighter">Acompte</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-indigo-50 text-indigo-600 tracking-tighter">Paiement complémentaire</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="px-8 py-5">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-6 h-4 bg-slate-100 rounded flex items-center justify-center text-[7px] font-bold text-slate-500 uppercase">
|
|
{{ pay.card.card.brand|default('CB') }}
|
|
</div>
|
|
<p class="text-[10px] font-bold text-slate-700 italic">**** {{ pay.card.card.last4|default('----') }}</p>
|
|
</div>
|
|
</td>
|
|
<td class="px-8 py-5 text-right font-black text-slate-900 italic text-sm">
|
|
{{ pay.amount|number_format(2, ',', ' ') }}€
|
|
</td>
|
|
<td class="px-8 py-5 text-right">
|
|
<div class="flex justify-end">
|
|
<a target="_blank" href="{{ path('gestion_contrat_view', {num: contrat.numReservation, idPaymentPdf: pay.id}) }}"
|
|
class="group relative flex items-center justify-center w-10 h-10 bg-blue-50 hover:bg-blue-600 text-blue-600 hover:text-white rounded-full transition-all duration-300 shadow-sm"
|
|
title="Télécharger le reçu">
|
|
|
|
{# Icône de téléchargement épurée #}
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 stroke-[2.5] transition-transform group-hover:scale-110" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
|
|
</svg>
|
|
|
|
{# Tooltip (optionnel) #}
|
|
<span class="absolute -top-8 scale-0 group-hover:scale-100 transition-all bg-slate-800 text-white text-[10px] px-2 py-1 rounded font-bold uppercase tracking-tighter">
|
|
PDF
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</td>
|
|
<td class="px-8 py-5 text-center">
|
|
<div class="inline-flex items-center gap-1.5 text-green-600">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path></svg>
|
|
<span class="text-[9px] font-black uppercase">Validé</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="5" class="px-8 py-10 text-center">
|
|
<p class="text-xs font-bold text-slate-400 italic uppercase tracking-widest">Aucune transaction enregistrée pour le moment</p>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|