```
✨ feat(event): Ajoute la liste des événements et la gestion d'absence d'événements.
Ajoute la liste des événements avec affichage de date, lieu, organisateur et un lien vers les détails. Gère l'absence d'événements.
```
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{% extends 'base.twig' %}
|
||||
|
||||
{% block title %}{{'events.title'|trans}}{% endblock %}
|
||||
{% block meta_description %}{{'events.description'|trans}}{% endblock %}
|
||||
{% block title %}{{ 'events.title'|trans }}{% endblock %}
|
||||
{% block meta_description %}{{ 'events.description'|trans }}{% endblock %}
|
||||
|
||||
{% block canonical_url %}<link rel="canonical" href="{{ url('app_events') }}" />{% endblock %}
|
||||
{% block breadcrumb_schema %}
|
||||
@@ -30,36 +30,98 @@
|
||||
{% block body %}
|
||||
<div class="container mx-auto p-4 md:p-8 pt-12">
|
||||
|
||||
<div class="max-w-3xl mx-auto text-center py-16 md:py-24 bg-white rounded-xl shadow-lg border border-gray-100">
|
||||
<h1 class="text-4xl font-extrabold text-gray-800 text-center mb-12">
|
||||
{{ 'events.list_main_title'|trans|default('Upcoming Events') }}
|
||||
</h1>
|
||||
|
||||
<span class="text-6xl text-indigo-500 mb-4 inline-block">
|
||||
{# Icône de calendrier/événements #}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-calendar-check"><rect width="18" height="18" x="3" y="4" rx="2" ry="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/><path d="m9 16 2 2 4-4"/></svg>
|
||||
</span>
|
||||
{#
|
||||
--- Events List Block ---
|
||||
This section assumes an 'events' iterable variable is passed to the template.
|
||||
Each item in 'events' is expected to be an object/array with:
|
||||
- title (string)
|
||||
- start_date (DateTime object)
|
||||
- end_date (DateTime object)
|
||||
- location (string)
|
||||
- organizer (string)
|
||||
- id (int/string for link)
|
||||
#}
|
||||
|
||||
<h1 class="text-4xl font-extrabold text-gray-800 mt-4 mb-3">
|
||||
{{ 'events.status_title'|trans }}
|
||||
</h1>
|
||||
{% if events is defined and events is not empty %}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
||||
{% for event in events %}
|
||||
<div class="bg-white rounded-xl shadow-lg border border-gray-100 p-6 flex flex-col justify-between transition duration-300 hover:shadow-xl hover:border-indigo-200">
|
||||
<div>
|
||||
{# Event Title #}
|
||||
<h2 class="text-2xl font-bold text-indigo-700 mb-4">{{ event.title }}</h2>
|
||||
|
||||
<p class="text-xl text-gray-600 mb-8">
|
||||
{{ 'events.status_message'|trans }}
|
||||
</p>
|
||||
<div class="space-y-3 text-gray-600">
|
||||
|
||||
{# Appel à l'action pour revenir ou voir les membres/contact #}
|
||||
<div class="flex flex-col sm:flex-row justify-center gap-4 mt-6">
|
||||
<a href="{{ url('app_members') }}" class="inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 transition duration-300 shadow-md">
|
||||
{{ 'events.button_members'|trans }}
|
||||
</a>
|
||||
<a href="{{ url('app_contact') }}" class="inline-flex items-center justify-center px-6 py-3 border border-gray-300 text-base font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 transition duration-300 shadow-md">
|
||||
{{ 'events.button_contact'|trans }}
|
||||
{# Date Block (Start Date / End Date) #}
|
||||
<p class="flex items-start text-sm">
|
||||
<svg class="w-4 h-4 mt-1 mr-2 flex-shrink-0 text-indigo-500" 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"></path></svg>
|
||||
<div>
|
||||
<span class="font-medium text-gray-800">{{ 'events.list.date_label'|trans|default('Date') }}:</span>
|
||||
<div class="text-xs mt-0.5">
|
||||
{{ event.start_date|date('d/m/Y H:i') }}
|
||||
{% if event.start_date|date('Ymd') != event.end_date|date('Ymd') %}
|
||||
- {{ event.end_date|date('d/m/Y H:i') }}
|
||||
{% else %}
|
||||
- {{ event.end_date|date('H:i') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
{# Location Block #}
|
||||
<p class="flex items-start text-sm">
|
||||
<svg class="w-4 h-4 mt-0.5 mr-2 flex-shrink-0 text-indigo-500" 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><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
|
||||
<div>
|
||||
<span class="font-medium text-gray-800">{{ 'events.list.location_label'|trans|default('Location') }}:</span>
|
||||
<div class="text-xs mt-0.5">{{ event.location }}</div>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
{# Organizer Block #}
|
||||
<p class="flex items-start text-sm">
|
||||
<svg class="w-4 h-4 mt-0.5 mr-2 flex-shrink-0 text-indigo-500" 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"></path></svg>
|
||||
<div>
|
||||
<span class="font-medium text-gray-800">{{ 'events.list.organizer_label'|trans|default('Organizer') }}:</span>
|
||||
<div class="text-xs mt-0.5">{{ event.organizer }}</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Details Link (assuming an 'id' or slug is available) #}
|
||||
<a href="{{ url('app_event_details', {id: event.id|default(loop.index)}) }}" class="mt-6 text-center w-full py-2 bg-indigo-50 hover:bg-indigo-100 text-indigo-600 font-semibold rounded-md text-sm transition duration-300 border border-indigo-100">
|
||||
{{ 'events.list.details_button'|trans|default('View Details') }}
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
{# Fallback if no events are found (repurposing the original styling) #}
|
||||
<div class="max-w-3xl mx-auto text-center py-16 md:py-24 bg-white rounded-xl shadow-lg border border-gray-100">
|
||||
|
||||
<span class="text-6xl text-gray-400 mb-4 inline-block">
|
||||
{# Icon: Calendar with an X #}
|
||||
<svg class="lucide lucide-calendar-x" xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="4" rx="2" ry="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/><path d="m14.5 12.5-5 5"/><path d="m9.5 12.5 5 5"/></svg>
|
||||
</span>
|
||||
|
||||
<h2 class="text-4xl font-extrabold text-gray-800 mt-4 mb-3">
|
||||
{{ 'events.no_events_title'|trans|default('No Upcoming Events') }}
|
||||
</h2>
|
||||
|
||||
<p class="text-xl text-gray-600 mb-8">
|
||||
{{ 'events.no_events_message'|trans|default('It looks like we don\'t have any events scheduled right now. Check back soon!') }}
|
||||
</p>
|
||||
|
||||
{# Action to contact us #}
|
||||
<a href="{{ url('app_contact') }}" class="inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 transition duration-300 shadow-md">
|
||||
{{ 'events.button_contact'|trans|default('Contact Us') }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Optionnel : Message pour les notifications #}
|
||||
<p class="text-sm text-gray-500 mt-10 border-t pt-6 max-w-sm mx-auto">
|
||||
{{ 'events.status_notification'|trans }}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user