Show purchased tickets in /mon-compte billets tab

- Load user's BilletOrders via BilletBuyer orders
- Display each ticket with: name, status badge (Actif/Expire/Annule),
  first scan date, event info (name, date, address), reference,
  order number, price, download PDF and view order buttons

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-21 17:01:13 +01:00
parent 51cda95efe
commit 85c2b1baa5
2 changed files with 68 additions and 2 deletions

View File

@@ -3,7 +3,9 @@
namespace App\Controller;
use App\Entity\Billet;
use App\Entity\BilletBuyer;
use App\Entity\BilletDesign;
use App\Entity\BilletOrder;
use App\Entity\Category;
use App\Entity\Event;
use App\Entity\Payout;
@@ -66,12 +68,27 @@ class AccountController extends AbstractController
$events = $paginator->paginate($eventsQuery, $request->query->getInt('page', 1), 10);
}
$orders = $em->getRepository(BilletBuyer::class)->findBy(
['user' => $user],
['createdAt' => 'DESC'],
);
$userTickets = [];
foreach ($orders as $order) {
$tickets = $em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
foreach ($tickets as $ticket) {
$userTickets[] = $ticket;
}
}
return $this->render('account/index.html.twig', [
'tab' => $tab,
'isOrganizer' => $isOrganizer,
'payouts' => $payouts,
'subAccounts' => $subAccounts,
'events' => $events,
'orders' => $orders,
'userTickets' => $userTickets,
'breadcrumbs' => [
self::BREADCRUMB_HOME,
self::BREADCRUMB_ACCOUNT,

View File

@@ -89,14 +89,63 @@
<a href="{{ path('app_account', {tab: 'settings'}) }}" class="flex-1 min-w-[100px] text-center py-3 border-3 border-gray-900 {{ tab == 'settings' ? 'bg-yellow-400' : 'bg-white' }} font-black uppercase text-xs tracking-widest transition-all">Parametres</a>
</div>
{% if tab == 'tickets' %}
<div class="card-brutal">
{% if tab == 'tickets' %}
<div class="card-brutal overflow-hidden">
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Mes billets</h2>
</div>
{% if userTickets|length > 0 %}
<div class="p-6">
{% for ticket in userTickets %}
{% set order = ticket.billetBuyer %}
{% set evt = order.event %}
<div class="border-2 border-gray-900 bg-white mb-4 overflow-hidden">
<div class="flex flex-col md:flex-row">
<div class="flex-1 p-4">
<div class="flex flex-wrap items-center gap-3 mb-2">
<span class="font-black uppercase text-sm">{{ ticket.billetName }}</span>
{% if ticket.state == 'valid' %}
<span class="badge-green text-[10px] font-black uppercase">Actif</span>
{% elseif ticket.state == 'expired' %}
<span class="badge-yellow text-[10px] font-black uppercase">Expire</span>
{% else %}
<span class="badge-red text-[10px] font-black uppercase">{{ ticket.state == 'invalid' ? 'Annule' : ticket.state }}</span>
{% endif %}
{% if ticket.firstScannedAt %}
<span class="text-[10px] font-bold text-gray-400">Scanne le {{ ticket.firstScannedAt|date('d/m/Y H:i') }}</span>
{% endif %}
</div>
<div class="space-y-1 text-sm font-bold text-gray-600 mb-3">
<p class="font-black text-gray-900">{{ evt.title }}</p>
<p>{{ evt.startAt|date('d/m/Y') }}{{ evt.startAt|date('H:i') }} a {{ evt.endAt|date('H:i') }}</p>
<p>{{ evt.address }}, {{ evt.zipcode }} {{ evt.city }}</p>
</div>
<div class="flex flex-wrap gap-4 text-xs font-bold text-gray-400">
<span>Ref: <span class="font-mono text-gray-600">{{ ticket.reference }}</span></span>
<span>Commande: <span class="text-gray-600">{{ order.orderNumber }}</span></span>
<span>Prix: <span class="text-indigo-600 font-black">{{ ticket.unitPriceHTDecimal|number_format(2, ',', ' ') }} &euro;</span></span>
</div>
</div>
<div class="flex items-center gap-2 p-4 border-t md:border-t-0 md:border-l border-gray-200">
<a href="{{ path('app_order_download_ticket', {orderNumber: order.orderNumber, token: order.accessToken, ticketReference: ticket.reference}) }}" class="px-3 py-2 border-2 border-gray-900 bg-white text-xs font-black uppercase hover:bg-indigo-600 hover:text-white transition-all" target="_blank">
Telecharger PDF
</a>
<a href="{{ path('app_order_public', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="px-3 py-2 border-2 border-gray-900 bg-white text-xs font-black uppercase hover:bg-gray-100 transition-all">
Commande
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="p-12 text-center">
<p class="text-gray-400 font-bold text-sm">Aucun billet pour le moment.</p>
</div>
{% endif %}
</div>
{% elseif tab == 'purchases' %}