- Add /evenements public page with Meilisearch search, KnpPaginator (12/page), event cards grid
- Add /evenement/{orgaSlug}/{id}-{eventSlug} public route with slug redirect
- Add Event::getSlug() method
- Update homepage stats with real event count
- Update organizer detail page to list their public events
- Update navbar: link Evenements to /evenements with active state
- Add copy URL button on edit event page (visible only when online)
- Add initCopyUrl() in app.js with clipboard API
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
156 lines
12 KiB
Twig
156 lines
12 KiB
Twig
{% extends 'base.html.twig' %}
|
|
|
|
{% block title %}{{ organizer.companyName ?? organizer.firstName ~ ' ' ~ organizer.lastName }} - E-Ticket{% endblock %}
|
|
{% block description %}Decouvrez les evenements de {{ organizer.companyName ?? organizer.firstName ~ ' ' ~ organizer.lastName }} sur E-Ticket{% endblock %}
|
|
{% block og_image %}
|
|
{% if organizer.logoName %}
|
|
<meta property="og:image" content="{{ absolute_url('/uploads/logos/' ~ organizer.logoName) }}">
|
|
{% else %}
|
|
<meta property="og:image" content="https://ticket.e-cosplay.fr/logo.png">
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% 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">
|
|
<div class="absolute inset-0 opacity-[0.03] pointer-events-none select-none overflow-hidden">
|
|
<span class="text-[20rem] font-black uppercase leading-none block -rotate-12 translate-y-10">ORGA</span>
|
|
</div>
|
|
|
|
<div class="max-w-4xl mx-auto relative z-10">
|
|
<a href="{{ path('app_organizers') }}" class="inline-flex items-center gap-2 text-sm font-black uppercase tracking-widest text-gray-500 hover:text-gray-900 transition-colors mb-8">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M15 19l-7-7 7-7"/></svg>
|
|
Retour aux organisateurs
|
|
</a>
|
|
|
|
<div class="flex flex-col md:flex-row items-center md:items-start gap-8">
|
|
{% if organizer.logoName %}
|
|
<div class="border-4 border-gray-900 flex items-center justify-center overflow-hidden bg-white p-3 shadow-[6px_6px_0px_rgba(0,0,0,1)]">
|
|
<img src="{{ ('/uploads/logos/' ~ organizer.logoName) | imagine_filter('organizer_logo') }}" alt="{{ organizer.companyName }}" class="h-[140px] w-auto object-contain">
|
|
</div>
|
|
{% else %}
|
|
<div class="w-32 h-32 bg-yellow-400 border-4 border-gray-900 flex items-center justify-center shadow-[6px_6px_0px_rgba(0,0,0,1)]">
|
|
<span class="text-5xl font-black">{{ organizer.firstName|first|upper }}{{ organizer.lastName|first|upper }}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="text-center md:text-left">
|
|
<h1 class="text-4xl md:text-6xl font-black uppercase tracking-tighter leading-[0.85] mb-4">
|
|
{{ organizer.companyName ?? organizer.firstName ~ ' ' ~ organizer.lastName }}
|
|
</h1>
|
|
{% if organizer.city %}
|
|
<p class="text-sm font-black uppercase tracking-widest text-gray-400">
|
|
{{ organizer.postalCode }} {{ organizer.city }}
|
|
</p>
|
|
{% endif %}
|
|
|
|
{% if organizer.website or organizer.facebook or organizer.instagram or organizer.twitter or organizer.tiktok %}
|
|
<div class="flex gap-3 mt-4 flex-wrap justify-center md:justify-start items-center">
|
|
{% if organizer.website %}
|
|
<a href="{{ organizer.website }}" target="_blank" class="w-9 h-9 flex items-center justify-center border-2 border-gray-900 bg-gray-100 hover:bg-gray-900 hover:text-white transition-all" title="Site internet">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/></svg>
|
|
</a>
|
|
{% endif %}
|
|
{% if organizer.facebook %}
|
|
<a href="{{ organizer.facebook }}" target="_blank" class="w-9 h-9 flex items-center justify-center border-2 border-gray-900 bg-[#1877F2] text-white hover:opacity-80 transition-all" title="Facebook">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
|
|
</a>
|
|
{% endif %}
|
|
{% if organizer.instagram %}
|
|
<a href="{{ organizer.instagram }}" target="_blank" class="w-9 h-9 flex items-center justify-center border-2 border-gray-900 bg-instagram text-white hover:opacity-80 transition-all" title="Instagram">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>
|
|
</a>
|
|
{% endif %}
|
|
{% if organizer.twitter %}
|
|
<a href="{{ organizer.twitter }}" target="_blank" class="w-9 h-9 flex items-center justify-center border-2 border-gray-900 bg-black text-white hover:opacity-80 transition-all" title="X (Twitter)">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
|
|
</a>
|
|
{% endif %}
|
|
{% if organizer.tiktok %}
|
|
<a href="{{ organizer.tiktok }}" target="_blank" class="w-9 h-9 flex items-center justify-center border-2 border-gray-900 bg-black text-white hover:opacity-80 transition-all" title="TikTok">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/></svg>
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="py-12 px-4">
|
|
<div class="max-w-4xl mx-auto">
|
|
<div class="bg-white border-4 border-gray-900 shadow-[6px_6px_0px_rgba(0,0,0,1)] overflow-hidden">
|
|
<div class="section-header">
|
|
<h2 class="text-sm font-black uppercase tracking-widest text-white">Informations</h2>
|
|
</div>
|
|
<div class="p-6">
|
|
<table class="detail-table">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-left text-xs font-black uppercase tracking-widest text-gray-400">Detail</th>
|
|
<th class="text-left text-xs font-black uppercase tracking-widest text-gray-400">Valeur</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="font-black text-xs uppercase tracking-widest text-gray-400">Raison sociale</td>
|
|
<td class="text-sm font-bold">{{ organizer.companyName ?? organizer.firstName ~ ' ' ~ organizer.lastName }}</td>
|
|
</tr>
|
|
{% if organizer.siret %}
|
|
<tr>
|
|
<td class="font-black text-xs uppercase tracking-widest text-gray-400">SIRET</td>
|
|
<td class="text-sm font-mono font-bold">{{ organizer.siret }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr>
|
|
<td class="font-black text-xs uppercase tracking-widest text-gray-400">Email</td>
|
|
<td class="text-sm font-bold">
|
|
<a href="mailto:{{ organizer.email }}" class="text-indigo-600 hover:underline">{{ organizer.email }}</a>
|
|
</td>
|
|
</tr>
|
|
{% if organizer.city %}
|
|
<tr>
|
|
<td class="font-black text-xs uppercase tracking-widest text-gray-400">Adresse</td>
|
|
<td class="text-sm font-bold">
|
|
{% if organizer.address %}{{ organizer.address }}, {% endif %}{{ organizer.postalCode }} {{ organizer.city }}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pb-16 px-4">
|
|
<div class="max-w-4xl mx-auto">
|
|
<div class="bg-white border-4 border-gray-900 shadow-[6px_6px_0px_rgba(0,0,0,1)] overflow-hidden">
|
|
<div class="section-header">
|
|
<h2 class="text-sm font-black uppercase tracking-widest text-white">Evenements ({{ events|length }})</h2>
|
|
</div>
|
|
{% if events|length > 0 %}
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-0">
|
|
{% for event in events %}
|
|
<a href="{{ path('app_event_detail', {orgaSlug: organizer.slug, id: event.id, eventSlug: event.slug}) }}" class="group p-6 border-b border-r border-gray-200 hover:bg-gray-50 transition-colors block">
|
|
<h3 class="font-black text-sm uppercase group-hover:text-indigo-600 transition-colors">{{ event.title }}</h3>
|
|
<p class="text-xs font-bold text-gray-500 mt-1">{{ event.startAt|date('d/m/Y') }} • {{ event.startAt|date('H:i') }} - {{ event.endAt|date('H:i') }}</p>
|
|
<p class="text-xs font-bold text-gray-400 mt-1">{{ event.zipcode }} {{ event.city }}</p>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="p-12 text-center">
|
|
<p class="text-gray-400 font-black text-lg uppercase">Aucun evenement pour le moment</p>
|
|
<p class="text-gray-500 font-bold mt-2 italic text-sm">Les evenements de cet organisateur apparaitront ici.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
{% endblock %}
|