Improve mobile/tablet responsive, fix structured data, update deploy schedule and fix HTML issues

- Add responsive breakpoints (sm/md) to event_detail.html.twig: adaptive titles, stacked ticket layout on mobile, reduced padding/spacing
- Add responsive breakpoints to order templates (guest, summary, public, payment, success): adaptive typography, padding, and layouts
- Fix BreadcrumbList JSON-LD: escape names with json_encode, remove item URL from last breadcrumb
- Update deploy.yml cron schedule from 3h/13h/19h/23h to 1h/22h
- Add <title> tags to rgpd_deletion.html.twig and rgpd_access.html.twig
- Add scope attributes to all <th> tags in rgpd_access.html.twig
- Replace deprecated width/cellpadding/cellspacing HTML attributes with CSS in scan_force_notification email

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-30 08:40:28 +02:00
parent 3a40de1ba0
commit 3468b1288d
11 changed files with 122 additions and 119 deletions

View File

@@ -56,8 +56,8 @@
{
"@type": "ListItem",
"position": {{ loop.index }},
"name": "{{ breadcrumb.name }}"{% if breadcrumb.url is defined and breadcrumb.url is not empty %},
"item": "{{ absolute_url(breadcrumb.url) }}"{% endif %}
"name": {{ breadcrumb.name|json_encode|raw }}{% if not loop.last and breadcrumb.url is defined and breadcrumb.url is not empty %},
"item": {{ absolute_url(breadcrumb.url)|json_encode|raw }}{% endif %}
}{% if not loop.last %},{% endif %}
{% endfor %}
]

View File

@@ -6,7 +6,7 @@
<h2>Validation forcee</h2>
<p>Un billet a ete <strong>force lors du scan</strong> sur votre evenement. Voici les details :</p>
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 20px 0; border: 2px solid #111827;">
<table style="width: 100%; border-spacing: 0; margin: 20px 0; border: 2px solid #111827;">
<tr style="background-color: #111827;">
<td colspan="2" style="padding: 12px 16px; color: #ffffff; font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em;">
Details du billet
@@ -36,7 +36,7 @@
</tr>
</table>
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 20px 0; border: 2px solid #eab308; background: #fefce8;">
<table style="width: 100%; border-spacing: 0; margin: 20px 0; border: 2px solid #eab308; background: #fefce8;">
<tr>
<td style="padding: 16px;">
<p style="margin: 0 0 4px; font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; color: #92400e;">Force par</p>

View File

@@ -14,32 +14,32 @@
{% block body %}
<div class="bg-[#fbfbfb] overflow-x-hidden italic font-sans">
<section class="relative bg-white border-b-8 border-gray-900 px-4 pt-20 pb-16">
<section class="relative bg-white border-b-8 border-gray-900 px-4 pt-14 pb-10 sm:pt-20 sm:pb-16">
<div class="absolute inset-0 opacity-[0.03] pointer-events-none select-none overflow-hidden">
<span class="text-[8rem] md:text-[20rem] font-black uppercase leading-none block -rotate-12 translate-y-10">EVENT</span>
<span class="text-[5rem] sm:text-[8rem] md:text-[20rem] font-black uppercase leading-none block -rotate-12 translate-y-10">EVENT</span>
</div>
<div class="max-w-4xl mx-auto relative z-10">
<h1 class="text-4xl md:text-6xl font-black uppercase tracking-tighter leading-[0.85] mb-6">{{ event.title }}</h1>
<h1 class="text-3xl sm:text-4xl md:text-6xl font-black uppercase tracking-tighter leading-[0.85] mb-4 sm:mb-6">{{ event.title }}</h1>
<div class="flex flex-wrap gap-6 text-sm font-bold">
<div class="flex flex-col sm:flex-row sm:flex-wrap gap-3 sm:gap-6 text-sm font-bold">
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-gray-400" 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"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
<svg class="w-5 h-5 text-gray-400 flex-shrink-0" 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"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
<span>{{ event.address }}, {{ event.zipcode }} {{ event.city }}</span>
</div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
<svg class="w-5 h-5 text-gray-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
<span>Du {{ event.startAt|date('d/m/Y H:i') }} au {{ event.endAt|date('d/m/Y H:i') }}</span>
</div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
<svg class="w-5 h-5 text-gray-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
<a href="{{ path('app_organizer_detail', {id: organizer.id, slug: organizer.slug}) }}" class="text-indigo-800 underline hover:text-indigo-950">{{ organizer.companyName ?? (organizer.firstName ~ ' ' ~ organizer.lastName) }}</a>
</div>
</div>
</div>
</section>
<section class="py-12 px-4">
<section class="py-8 sm:py-12 px-4">
<div class="max-w-4xl mx-auto">
{% for message in app.flashes('success') %}
<div class="flash-success"><p class="font-black text-sm">{{ message }}</p></div>
@@ -52,14 +52,14 @@
<div class="flex flex-col md:flex-row">
<div class="md:w-[300px] flex-shrink-0">
{% if event.eventMainPictureName %}
<img src="{{ ('/uploads/events/' ~ event.eventMainPictureName) | imagine_filter('medium') }}" alt="{{ event.title }}" class="w-full max-h-[300px] object-contain">
<img src="{{ ('/uploads/events/' ~ event.eventMainPictureName) | imagine_filter('medium') }}" alt="{{ event.title }}" class="w-full max-h-[200px] sm:max-h-[300px] object-contain">
{% else %}
<div class="w-full h-[250px] bg-gray-100 flex items-center justify-center">
<div class="w-full h-[180px] sm:h-[250px] bg-gray-100 flex items-center justify-center">
<span class="text-5xl opacity-20">&#128247;</span>
</div>
{% endif %}
</div>
<div class="p-6 flex-1">
<div class="p-4 sm:p-6 flex-1">
{% if event.description %}
<div class="prose prose-sm max-w-none font-bold text-gray-700 leading-relaxed">
{{ event.description|raw }}
@@ -103,7 +103,7 @@
</div>
{% endif %}
{% if not event_ended %}
<div class="p-6">
<div class="p-4 sm:p-6">
{% for category in categories %}
{% if category.active %}
{% set category_billets = billets[category.id] ?? [] %}
@@ -113,16 +113,16 @@
{% if category_billets|length > 0 %}
<div class="space-y-3">
{% for billet in category_billets %}
<div class="border-2 border-gray-900 bg-white p-4" data-cart-item data-billet-id="{{ billet.id }}" data-price="{{ billet.priceHTDecimal }}" data-max="{{ billet.quantity ?? 0 }}">
<div class="flex flex-col md:flex-row md:items-center gap-4">
<div class="flex items-center gap-4 flex-1 min-w-0">
<div class="border-2 border-gray-900 bg-white p-3 sm:p-4" data-cart-item data-billet-id="{{ billet.id }}" data-price="{{ billet.priceHTDecimal }}" data-max="{{ billet.quantity ?? 0 }}">
<div class="flex flex-col gap-3 sm:gap-4">
<div class="flex items-center gap-3 sm:gap-4 min-w-0">
{% if billet.pictureName %}
<img src="{{ ('/uploads/billets/' ~ billet.pictureName) | imagine_filter('thumbnail') }}" alt="{{ billet.name }}" class="w-16 h-16 object-cover border border-gray-300 flex-shrink-0">
<img src="{{ ('/uploads/billets/' ~ billet.pictureName) | imagine_filter('thumbnail') }}" alt="{{ billet.name }}" class="w-12 h-12 sm:w-16 sm:h-16 object-cover border border-gray-300 flex-shrink-0">
{% endif %}
<div class="min-w-0">
<p class="font-black uppercase text-sm">{{ billet.name }}</p>
<div class="min-w-0 flex-1">
<p class="font-black uppercase text-xs sm:text-sm">{{ billet.name }}</p>
{% if billet.description %}
<p class="text-xs text-gray-500 font-bold mt-1">{{ billet.description }}</p>
<p class="text-xs text-gray-500 font-bold mt-1 line-clamp-2">{{ billet.description }}</p>
{% endif %}
<p class="text-[10px] font-bold mt-1" data-stock-label>
{% if not billet.unlimited and billet.quantity is not null %}
@@ -136,18 +136,19 @@
{% endif %}
</p>
</div>
<p class="font-black text-indigo-600 text-base sm:text-lg flex-shrink-0 md:hidden">{{ billet.priceHTDecimal|number_format(2, ',', ' ') }} &euro;</p>
</div>
<div class="flex items-center gap-4 flex-shrink-0">
<p class="font-black text-indigo-600 text-lg w-24 text-right">{{ billet.priceHTDecimal|number_format(2, ',', ' ') }} &euro;</p>
<div class="flex items-center justify-between gap-3 sm:gap-4">
<p class="font-black text-indigo-600 text-lg w-24 text-right hidden md:block flex-shrink-0">{{ billet.priceHTDecimal|number_format(2, ',', ' ') }} &euro;</p>
<div class="flex items-center border-2 border-gray-900">
<button type="button" data-cart-minus aria-label="Retirer un {{ billet.name }}" class="w-9 h-9 flex items-center justify-center font-black text-lg hover:bg-gray-100 transition-all cursor-pointer select-none">-</button>
<input type="number" data-cart-qty min="0" max="{{ billet.quantity ?? 99 }}" value="0" aria-label="Quantite {{ billet.name }}" class="w-12 h-9 text-center font-black text-sm border-x-2 border-gray-900 outline-none" readonly>
<button type="button" data-cart-plus aria-label="Ajouter un {{ billet.name }}" class="w-9 h-9 flex items-center justify-center font-black text-lg hover:bg-gray-100 transition-all cursor-pointer select-none">+</button>
<div class="flex items-center border-2 border-gray-900 flex-shrink-0">
<button type="button" data-cart-minus aria-label="Retirer un {{ billet.name }}" class="w-8 h-8 sm:w-9 sm:h-9 flex items-center justify-center font-black text-lg hover:bg-gray-100 transition-all cursor-pointer select-none">-</button>
<input type="number" data-cart-qty min="0" max="{{ billet.quantity ?? 99 }}" value="0" aria-label="Quantite {{ billet.name }}" class="w-10 h-8 sm:w-12 sm:h-9 text-center font-black text-sm border-x-2 border-gray-900 outline-none" readonly>
<button type="button" data-cart-plus aria-label="Ajouter un {{ billet.name }}" class="w-8 h-8 sm:w-9 sm:h-9 flex items-center justify-center font-black text-lg hover:bg-gray-100 transition-all cursor-pointer select-none">+</button>
</div>
<p class="font-black text-sm w-24 text-right" data-cart-line-total>0,00 &euro;</p>
<p class="font-black text-sm w-20 sm:w-24 text-right flex-shrink-0" data-cart-line-total>0,00 &euro;</p>
</div>
</div>
</div>
@@ -160,19 +161,19 @@
{% endif %}
{% endfor %}
<div class="border-t-3 border-gray-900 pt-6 mt-6">
<div class="flex items-center justify-between mb-4">
<span class="font-black uppercase text-sm tracking-widest">Total</span>
<span class="font-black text-2xl text-indigo-600" id="cart-total">0,00 &euro;</span>
<div class="border-t-3 border-gray-900 pt-4 sm:pt-6 mt-4 sm:mt-6">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<span class="font-black uppercase text-xs sm:text-sm tracking-widest">Total</span>
<span class="font-black text-xl sm:text-2xl text-indigo-600" id="cart-total">0,00 &euro;</span>
</div>
<div class="flex items-center justify-between mb-6">
<span class="text-xs font-bold text-gray-400 uppercase tracking-widest">Articles</span>
<div class="flex items-center justify-between mb-4 sm:mb-6">
<span class="text-[10px] sm:text-xs font-bold text-gray-400 uppercase tracking-widest">Articles</span>
<span class="font-black text-sm" id="cart-count">0</span>
</div>
<div id="cart-error" class="hidden flash-error mb-4">
<p class="font-black text-sm" id="cart-error-text"></p>
</div>
<button type="button" id="cart-checkout" disabled data-order-url="{{ path('app_order_create', {id: event.id}) }}" class="w-full btn-brutal font-black uppercase text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all disabled:opacity-30 disabled:cursor-not-allowed">
<button type="button" id="cart-checkout" disabled data-order-url="{{ path('app_order_create', {id: event.id}) }}" class="w-full btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all disabled:opacity-30 disabled:cursor-not-allowed">
Commander
</button>
</div>
@@ -185,21 +186,21 @@
<div class="section-header">
<h2 class="text-sm font-black uppercase tracking-widest text-white">Emplacement</h2>
</div>
<div id="event-map" class="w-full h-[300px]" data-address="{{ event.address }}, {{ event.zipcode }} {{ event.city }}"></div>
<div id="event-map" class="w-full h-[200px] sm:h-[300px]" data-address="{{ event.address }}, {{ event.zipcode }} {{ event.city }}"></div>
</div>
</div>
</section>
<section class="py-12 px-4">
<div class="max-w-4xl mx-auto flex flex-col lg:flex-row gap-8">
<section class="py-8 sm:py-12 px-4">
<div class="max-w-4xl mx-auto flex flex-col lg:flex-row gap-6 sm:gap-8">
<div class="flex-1">
<div class="card-brutal overflow-hidden">
<div class="section-header">
<h2 class="text-sm font-black uppercase tracking-widest text-white">Organisateur</h2>
</div>
<div class="p-6">
<div class="flex items-center gap-4 mb-6">
<div class="p-4 sm:p-6">
<div class="flex items-center gap-3 sm:gap-4 mb-4 sm:mb-6">
{% if organizer.logoName %}
<div class="border-3 border-gray-900 overflow-hidden bg-white p-1 shadow-[4px_4px_0px_rgba(0,0,0,1)]">
<img src="{{ ('/uploads/logos/' ~ organizer.logoName) | imagine_filter('thumbnail') }}" alt="{{ organizer.companyName }}" class="h-[60px] w-auto object-contain">
@@ -231,7 +232,7 @@
<div class="section-header">
<h2 class="text-sm font-black uppercase tracking-widest text-white">Contacter l'organisateur</h2>
</div>
<div class="p-6">
<div class="p-4 sm:p-6">
<form method="post" action="{{ path('app_event_contact', {id: event.id}) }}" class="form-col">
<div class="form-row">
<div class="form-group">

View File

@@ -2,20 +2,20 @@
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Recapitulatif</h2>
</div>
<div class="p-6">
<p class="font-black uppercase text-sm tracking-widest mb-4">{{ order.event.title }}</p>
<div class="p-4 sm:p-6">
<p class="font-black uppercase text-xs sm:text-sm tracking-widest mb-3 sm:mb-4">{{ order.event.title }}</p>
{% for item in order.items %}
<div class="flex justify-between py-2 {{ not loop.last ? 'border-b border-gray-200' : '' }}">
<div>
<p class="font-bold text-sm">{{ item.billetName }}</p>
<div class="flex justify-between gap-2 py-2 {{ not loop.last ? 'border-b border-gray-200' : '' }}">
<div class="min-w-0">
<p class="font-bold text-sm truncate">{{ item.billetName }}</p>
<p class="text-xs text-gray-400 font-bold">x{{ item.quantity }}{{ item.unitPriceHTDecimal|number_format(2, ',', ' ') }} &euro;/u</p>
</div>
<p class="font-black text-sm text-indigo-600">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</p>
<p class="font-black text-sm text-indigo-600 flex-shrink-0">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</p>
</div>
{% endfor %}
<div class="flex justify-between pt-4 mt-4 border-t-2 border-gray-900">
<div class="flex justify-between pt-3 sm:pt-4 mt-3 sm:mt-4 border-t-2 border-gray-900">
<span class="font-black uppercase text-sm">Total HT</span>
<span class="font-black text-lg text-indigo-600">{{ order.totalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
</div>

View File

@@ -4,14 +4,14 @@
{% block body %}
<div class="page-container">
<h1 class="text-3xl font-black uppercase tracking-tighter italic heading-page">Vos informations</h1>
<p class="font-bold text-gray-600 italic mb-2">Commande {{ order.orderNumber }}{{ order.event.title }}</p>
<h1 class="text-2xl sm:text-3xl font-black uppercase tracking-tighter italic heading-page">Vos informations</h1>
<p class="font-bold text-gray-600 italic mb-2 text-sm sm:text-base">Commande {{ order.orderNumber }}{{ order.event.title }}</p>
{% for message in app.flashes('error') %}
<div class="flash-error"><p class="font-black text-sm">{{ message }}</p></div>
{% endfor %}
<div class="flex flex-col lg:flex-row gap-8">
<div class="flex flex-col lg:flex-row gap-6 sm:gap-8">
<div class="flex-1">
<div class="card-brutal">
<form method="post" action="{{ path('app_order_guest', {id: order.id}) }}" class="form-col">
@@ -32,7 +32,7 @@
</div>
<div>
<button type="submit" class="w-full btn-brutal font-black uppercase text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
<button type="submit" class="w-full btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
Continuer vers le paiement
</button>
</div>

View File

@@ -7,14 +7,14 @@
{% endblock %}
{% block body %}
<div class="w-full md:w-[80%] lg:w-[60%] mx-auto py-12 px-4">
<div class="w-full md:w-[80%] lg:w-[60%] mx-auto py-8 sm:py-12 px-4">
<div class="card-brutal overflow-hidden mb-6">
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Evenement</h2>
</div>
<div class="p-6">
<h1 class="text-2xl font-black uppercase tracking-tighter mb-2">{{ order.event.title }}</h1>
<div class="p-4 sm:p-6">
<h1 class="text-xl sm:text-2xl font-black uppercase tracking-tighter mb-2">{{ order.event.title }}</h1>
<p class="text-sm font-bold text-gray-600 mb-1">{{ order.event.startAt|date('d/m/Y') }}{{ order.event.startAt|date('H:i') }} a {{ order.event.endAt|date('H:i') }}</p>
<p class="text-sm font-bold text-gray-600 mb-1">{{ order.event.address }}, {{ order.event.zipcode }} {{ order.event.city }}</p>
<p class="text-sm font-bold text-gray-400">Par {{ order.event.account.companyName ?? (order.event.account.firstName ~ ' ' ~ order.event.account.lastName) }}</p>
@@ -26,7 +26,7 @@
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Acheteur</h2>
</div>
<div class="p-6 flex flex-wrap gap-6">
<div class="p-4 sm:p-6 flex flex-wrap gap-4 sm:gap-6">
<div>
<p class="text-[10px] font-black uppercase tracking-widest text-gray-400 mb-1">Nom</p>
<p class="text-sm font-bold">{{ order.lastName }}</p>
@@ -35,9 +35,9 @@
<p class="text-[10px] font-black uppercase tracking-widest text-gray-400 mb-1">Prenom</p>
<p class="text-sm font-bold">{{ order.firstName }}</p>
</div>
<div>
<div class="min-w-0">
<p class="text-[10px] font-black uppercase tracking-widest text-gray-400 mb-1">Email</p>
<p class="text-sm font-bold">{{ order.email }}</p>
<p class="text-sm font-bold break-all">{{ order.email }}</p>
</div>
</div>
</div>
@@ -46,33 +46,33 @@
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Billets</h2>
</div>
<div class="p-6">
<div class="p-4 sm:p-6">
{% for item in order.items %}
<div class="border-2 border-gray-900 bg-white p-4 {{ not loop.last ? 'mb-3' : '' }}">
<div class="flex flex-col md:flex-row md:items-center gap-4">
<div class="flex items-center gap-4 flex-1 min-w-0">
<div class="border-2 border-gray-900 bg-white p-3 sm:p-4 {{ not loop.last ? 'mb-3' : '' }}">
<div class="flex flex-col gap-3">
<div class="flex items-center gap-3 sm:gap-4 min-w-0">
{% if item.billet and item.billet.pictureName %}
<img src="{{ ('/uploads/billets/' ~ item.billet.pictureName) | imagine_filter('thumbnail') }}" alt="{{ item.billetName }}" class="w-16 h-16 object-cover border border-gray-300 flex-shrink-0">
<img src="{{ ('/uploads/billets/' ~ item.billet.pictureName) | imagine_filter('thumbnail') }}" alt="{{ item.billetName }}" class="w-12 h-12 sm:w-16 sm:h-16 object-cover border border-gray-300 flex-shrink-0">
{% endif %}
<div class="min-w-0">
<p class="font-black uppercase text-sm">{{ item.billetName }}</p>
<div class="min-w-0 flex-1">
<p class="font-black uppercase text-xs sm:text-sm">{{ item.billetName }}</p>
{% if item.billet and item.billet.description %}
<p class="text-xs text-gray-500 font-bold mt-1">{{ item.billet.description }}</p>
<p class="text-xs text-gray-500 font-bold mt-1 line-clamp-2">{{ item.billet.description }}</p>
{% endif %}
</div>
</div>
<div class="flex items-center gap-6 flex-shrink-0">
<div class="flex items-center justify-end gap-4 sm:gap-6 flex-shrink-0">
<span class="text-sm font-bold text-gray-400">x{{ item.quantity }}</span>
<span class="font-black text-sm">{{ item.unitPriceHTDecimal|number_format(2, ',', ' ') }} &euro;/u</span>
<span class="font-black text-lg text-indigo-600">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
<span class="font-black text-base sm:text-lg text-indigo-600">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
</div>
</div>
</div>
{% endfor %}
<div class="flex justify-between pt-4 mt-4 border-t-3 border-gray-900">
<span class="font-black uppercase tracking-widest">Total</span>
<span class="font-black text-2xl text-indigo-600">{{ order.totalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
<span class="font-black uppercase text-sm sm:text-base tracking-widest">Total</span>
<span class="font-black text-xl sm:text-2xl text-indigo-600">{{ order.totalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
</div>
</div>
</div>
@@ -81,9 +81,9 @@
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Paiement securise</h2>
</div>
<div class="p-6">
<div class="p-4 sm:p-6">
<noscript>
<a href="{{ path('app_order_checkout_fallback', {id: order.id}) }}" class="w-full btn-brutal font-black uppercase text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all block text-center">
<a href="{{ path('app_order_checkout_fallback', {id: order.id}) }}" class="w-full btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all block text-center">
Payer {{ order.totalHTDecimal|number_format(2, ',', ' ') }} &euro; via Stripe
</a>
</noscript>
@@ -91,7 +91,7 @@
<div id="payment-message" class="hidden flash-error mb-4">
<p class="font-black text-sm" id="payment-message-text"></p>
</div>
<button type="button" id="payment-submit" class="w-full btn-brutal font-black uppercase text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
<button type="button" id="payment-submit" class="w-full btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
Payer {{ order.totalHTDecimal|number_format(2, ',', ' ') }} &euro;
</button>
<p class="text-[10px] font-bold text-gray-400 mt-4 text-center">Paiement securise par Stripe</p>

View File

@@ -4,15 +4,15 @@
{% block body %}
<div class="page-container">
<h1 class="text-3xl font-black uppercase tracking-tighter italic heading-page">Ma commande</h1>
<p class="font-bold text-gray-600 italic mb-2">Commande {{ order.orderNumber }}{{ order.event.title }}</p>
<h1 class="text-2xl sm:text-3xl font-black uppercase tracking-tighter italic heading-page">Ma commande</h1>
<p class="font-bold text-gray-600 italic mb-2 text-sm sm:text-base">Commande {{ order.orderNumber }}{{ order.event.title }}</p>
<div class="card-brutal overflow-hidden mb-6">
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Evenement</h2>
</div>
<div class="p-6">
<p class="font-black uppercase text-lg tracking-tighter mb-2">{{ order.event.title }}</p>
<div class="p-4 sm:p-6">
<p class="font-black uppercase text-base sm:text-lg tracking-tighter mb-2">{{ order.event.title }}</p>
<div class="space-y-1 text-sm font-bold text-gray-600">
<p>{{ order.event.startAt|date('d/m/Y') }}{{ order.event.startAt|date('H:i') }} a {{ order.event.endAt|date('H:i') }}</p>
<p>{{ order.event.address }}, {{ order.event.zipcode }} {{ order.event.city }}</p>
@@ -21,15 +21,15 @@
</div>
</div>
<div class="flex flex-col lg:flex-row gap-8">
<div class="flex flex-col lg:flex-row gap-6 sm:gap-8">
<div class="flex-1">
<div class="card-brutal overflow-hidden mb-6">
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Acheteur</h2>
</div>
<div class="p-6 space-y-2">
<div class="p-4 sm:p-6 space-y-2">
<p class="text-sm font-bold">{{ order.firstName }} {{ order.lastName }}</p>
<p class="text-sm font-bold text-gray-500">{{ order.email }}</p>
<p class="text-sm font-bold text-gray-500 break-all">{{ order.email }}</p>
<p class="text-sm font-bold">
{% if order.status == 'paid' %}
<span class="badge-green text-xs font-black uppercase">Payee</span>
@@ -49,7 +49,7 @@
{% endif %}
{% if order.status == 'paid' %}
<div class="mt-3">
<a href="{{ path('app_order_invoice', {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-indigo-600 hover:text-white transition-all" target="_blank">
<a href="{{ path('app_order_invoice', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="inline-block 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 la facture
</a>
</div>
@@ -62,24 +62,26 @@
<div class="section-header">
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Vos billets</h2>
</div>
<div class="p-6">
<div class="p-4 sm:p-6">
{% for ticket in tickets %}
<div class="flex flex-wrap items-center gap-4 py-3 {{ not loop.last ? 'border-b border-gray-200' : '' }}">
<div class="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 py-3 {{ not loop.last ? 'border-b border-gray-200' : '' }}">
<div class="flex-1 min-w-0">
<p class="font-black uppercase text-sm">{{ ticket.billetName }}</p>
<p class="text-xs font-mono text-gray-400">{{ ticket.reference }}</p>
<p class="text-xs font-mono text-gray-400 truncate">{{ ticket.reference }}</p>
</div>
<div class="flex items-center flex-wrap gap-2 sm:gap-4">
<span class="font-black text-sm text-indigo-600">{{ ticket.unitPriceHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
{% if ticket.state == 'valid' %}
<span class="badge-green text-[10px] font-black uppercase">Valide</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">Invalide</span>
{% endif %}
<a href="{{ path('app_order_download_ticket', {orderNumber: order.orderNumber, token: order.accessToken, ticketReference: ticket.reference}) }}" class="px-3 py-1 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>
</div>
<span class="font-black text-sm text-indigo-600">{{ ticket.unitPriceHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
{% if ticket.state == 'valid' %}
<span class="badge-green text-[10px] font-black uppercase">Valide</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">Invalide</span>
{% endif %}
<a href="{{ path('app_order_download_ticket', {orderNumber: order.orderNumber, token: order.accessToken, ticketReference: ticket.reference}) }}" class="px-3 py-1 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>
</div>
{% endfor %}
</div>

View File

@@ -5,26 +5,26 @@
{% block body %}
<div class="page-container">
<div class="max-w-xl mx-auto text-center">
<div class="card-brutal p-8">
<div class="card-brutal p-5 sm:p-8">
{% if failed|default(false) %}
<div class="text-6xl mb-4 text-red-600">&#10007;</div>
<h1 class="text-3xl font-black uppercase tracking-tighter italic heading-page mb-4">Paiement echoue</h1>
<p class="font-bold text-gray-600 mb-6">Le paiement n'a pas abouti. Vous pouvez reessayer.</p>
<a href="{{ path('app_order_payment', {id: order.id}) }}" class="btn-brutal font-black uppercase text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
<div class="text-5xl sm:text-6xl mb-4 text-red-600">&#10007;</div>
<h1 class="text-2xl sm:text-3xl font-black uppercase tracking-tighter italic heading-page mb-4">Paiement echoue</h1>
<p class="font-bold text-gray-600 mb-6 text-sm sm:text-base">Le paiement n'a pas abouti. Vous pouvez reessayer.</p>
<a href="{{ path('app_order_payment', {id: order.id}) }}" class="btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest bg-indigo-600 text-white hover:bg-indigo-800 transition-all">
Reessayer le paiement
</a>
{% else %}
<div class="text-6xl mb-4 text-green-600">&#10003;</div>
<h1 class="text-3xl font-black uppercase tracking-tighter italic heading-page mb-4">Commande confirmee</h1>
<div class="text-5xl sm:text-6xl mb-4 text-green-600">&#10003;</div>
<h1 class="text-2xl sm:text-3xl font-black uppercase tracking-tighter italic heading-page mb-4">Commande confirmee</h1>
<p class="font-bold text-gray-600 mb-2">Merci {{ order.firstName }} !</p>
<p class="text-sm font-bold text-gray-500 mb-6">Votre commande <span class="font-mono text-gray-900">{{ order.orderNumber }}</span> a bien ete enregistree.</p>
<p class="text-sm font-bold text-gray-500 mb-6">Votre commande <span class="font-mono text-gray-900 break-all">{{ order.orderNumber }}</span> a bien ete enregistree.</p>
<div class="border-2 border-gray-900 p-4 bg-gray-50 text-left mb-6">
<div class="border-2 border-gray-900 p-3 sm:p-4 bg-gray-50 text-left mb-6">
<p class="text-xs font-black uppercase tracking-widest text-gray-500 mb-2">Details</p>
{% for item in order.items %}
<div class="flex justify-between py-1 text-sm font-bold">
<span>{{ item.billetName }} x{{ item.quantity }}</span>
<span>{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
<div class="flex justify-between gap-2 py-1 text-sm font-bold">
<span class="min-w-0 truncate">{{ item.billetName }} x{{ item.quantity }}</span>
<span class="flex-shrink-0">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} &euro;</span>
</div>
{% endfor %}
<div class="flex justify-between pt-2 mt-2 border-t-2 border-gray-900 font-black">
@@ -33,13 +33,13 @@
</div>
</div>
<p class="text-xs font-bold text-gray-400 mb-6">Vos billets ont ete envoyes a {{ order.email }}</p>
<p class="text-xs font-bold text-gray-400 mb-6">Vos billets ont ete envoyes a <span class="break-all">{{ order.email }}</span></p>
<div class="flex flex-col gap-3">
<a href="{{ path('app_order_invoice', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="btn-brutal font-black uppercase text-sm tracking-widest hover:bg-gray-100 transition-all" target="_blank">
<a href="{{ path('app_order_invoice', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest hover:bg-gray-100 transition-all" target="_blank">
Telecharger la facture
</a>
<a href="{{ path('app_order_public', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="btn-brutal font-black uppercase text-sm tracking-widest hover:bg-indigo-600 hover:text-white transition-all">
<a href="{{ path('app_order_public', {orderNumber: order.orderNumber, token: order.accessToken}) }}" class="btn-brutal font-black uppercase text-xs sm:text-sm tracking-widest hover:bg-indigo-600 hover:text-white transition-all">
Voir ma commande
</a>
<a href="{{ path('app_home') }}" class="text-sm font-bold text-gray-500 hover:text-gray-900 transition-colors">

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><style>
<head><meta charset="UTF-8"><title>Droit d'acces aux donnees personnelles - E-Cosplay</title><style>
body { font-family: DejaVu Sans, sans-serif; font-size: 11px; color: #111; }
h1 { font-size: 18px; margin-bottom: 5px; }
h2 { font-size: 14px; margin-top: 20px; border-bottom: 1px solid #ccc; padding-bottom: 3px; }
@@ -20,14 +20,14 @@ th { background: #f5f5f5; font-weight: bold; }
{% for entry in data %}
<h2>Session #{{ loop.index }}{{ entry.visitor.createdAt|date('d/m/Y H:i') }}</h2>
<table>
<tr><th>Appareil</th><td>{{ entry.visitor.deviceType }}</td><th>OS</th><td>{{ entry.visitor.os ?? 'Inconnu' }}</td></tr>
<tr><th>Navigateur</th><td>{{ entry.visitor.browser ?? 'Inconnu' }}</td><th>Langue</th><td>{{ entry.visitor.language ?? 'Inconnu' }}</td></tr>
<tr><th>Ecran</th><td>{{ entry.visitor.screenWidth ?? '?' }}x{{ entry.visitor.screenHeight ?? '?' }}</td><th>Compte lie</th><td>{{ entry.visitor.user ? entry.visitor.user.email : 'Non' }}</td></tr>
<tr><th scope="row">Appareil</th><td>{{ entry.visitor.deviceType }}</td><th scope="row">OS</th><td>{{ entry.visitor.os ?? 'Inconnu' }}</td></tr>
<tr><th scope="row">Navigateur</th><td>{{ entry.visitor.browser ?? 'Inconnu' }}</td><th scope="row">Langue</th><td>{{ entry.visitor.language ?? 'Inconnu' }}</td></tr>
<tr><th scope="row">Ecran</th><td>{{ entry.visitor.screenWidth ?? '?' }}x{{ entry.visitor.screenHeight ?? '?' }}</td><th scope="row">Compte lie</th><td>{{ entry.visitor.user ? entry.visitor.user.email : 'Non' }}</td></tr>
</table>
{% if entry.events|length > 0 %}
<table>
<thead><tr><th>Date</th><th>Page</th><th>Titre</th><th>Referrer</th></tr></thead>
<thead><tr><th scope="col">Date</th><th scope="col">Page</th><th scope="col">Titre</th><th scope="col">Referrer</th></tr></thead>
<tbody>
{% for event in entry.events %}
<tr>

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><style>
<head><meta charset="UTF-8"><title>Attestation de suppression de donnees - E-Cosplay</title><style>
body { font-family: DejaVu Sans, sans-serif; font-size: 12px; color: #111; }
h1 { font-size: 20px; text-align: center; margin-bottom: 30px; }
.content { max-width: 500px; margin: 0 auto; }