From 7e61371244266378f4aff88d6412ca3d69439ea7 Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Tue, 2 Dec 2025 21:48:03 +0100 Subject: [PATCH] =?UTF-8?q?```=20=E2=9C=A8=20feat(EventsController):=20Aff?= =?UTF-8?q?iche=20la=20liste=20des=20=C3=A9v=C3=A9nements=20et=20les=20d?= =?UTF-8?q?=C3=A9tails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute l'affichage des événements et de leurs détails. Ajoute aussi la gestion des affiches. ``` --- assets/admin.js | 1 - config/packages/vich_uploader.yaml | 22 +++ migrations/Version20251202200532.php | 35 ++++ src/Controller/Admin/AdminController.php | 42 +++- src/Controller/EventsController.php | 16 +- src/Entity/Event.php | 226 ++++++++++++++++++++++ src/EventSubscriber/SitemapSubscriber.php | 14 +- src/Form/EventType.php | 62 ++++++ src/Repository/EventRepository.php | 43 ++++ src/Service/Events/AdvertEvent.php | 23 +++ src/Service/Events/EventSubscriber.php | 34 ++++ templates/admin/events.twig | 104 ++++++++++ templates/admin/events/add.twig | 171 ++++++++++++++++ templates/event.twig | 150 ++++++++------ templates/event_view.twig | 116 +++++++++++ templates/mails/event/new.twig | 75 +++++++ templates/txt-mails/event/new.twig | 17 ++ translations/messages.cn.yaml | 9 + translations/messages.en.yaml | 11 ++ translations/messages.fr.yaml | 13 ++ 20 files changed, 1111 insertions(+), 73 deletions(-) create mode 100644 migrations/Version20251202200532.php create mode 100644 src/Entity/Event.php create mode 100644 src/Form/EventType.php create mode 100644 src/Repository/EventRepository.php create mode 100644 src/Service/Events/AdvertEvent.php create mode 100644 src/Service/Events/EventSubscriber.php create mode 100644 templates/admin/events.twig create mode 100644 templates/admin/events/add.twig create mode 100644 templates/event_view.twig create mode 100644 templates/mails/event/new.twig create mode 100644 templates/txt-mails/event/new.twig diff --git a/assets/admin.js b/assets/admin.js index bf73389..34c0022 100644 --- a/assets/admin.js +++ b/assets/admin.js @@ -1,3 +1,2 @@ import './admin.scss' -import * as Turbo from "@hotwired/turbo" diff --git a/config/packages/vich_uploader.yaml b/config/packages/vich_uploader.yaml index 9584a85..4d763c2 100644 --- a/config/packages/vich_uploader.yaml +++ b/config/packages/vich_uploader.yaml @@ -52,6 +52,28 @@ vich_uploader: inject_on_load: true delete_on_update: true delete_on_remove: true + product: + uri_prefix: /storage/product + upload_destination: '%kernel.project_dir%/public/storage/product' + namer: Vich\UploaderBundle\Naming\UniqidNamer # Replaced namer + inject_on_load: true + delete_on_update: true + delete_on_remove: true + events: + uri_prefix: /storage/events + upload_destination: '%kernel.project_dir%/public/storage/events' + namer: Vich\UploaderBundle\Naming\UniqidNamer # Replaced namer + inject_on_load: true + delete_on_update: true + delete_on_remove: true + event_picture: + uri_prefix: /event_picture/events + upload_destination: '%kernel.project_dir%/public/storage/event_picture' + namer: Vich\UploaderBundle\Naming\UniqidNamer # Replaced namer + directory_namer: App\VichUploader\DirectoryNamer\EventName + inject_on_load: true + delete_on_update: true + delete_on_remove: true #mappings: # products: # uri_prefix: /images/products diff --git a/migrations/Version20251202200532.php b/migrations/Version20251202200532.php new file mode 100644 index 0000000..df74426 --- /dev/null +++ b/migrations/Version20251202200532.php @@ -0,0 +1,35 @@ +addSql('CREATE TABLE event (id SERIAL NOT NULL, title VARCHAR(255) NOT NULL, start_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, end_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, location VARCHAR(255) NOT NULL, organizer VARCHAR(255) NOT NULL, events_file_name VARCHAR(255) DEFAULT NULL, events_dimensions JSON DEFAULT NULL, events_size VARCHAR(255) DEFAULT NULL, events_mine_type VARCHAR(255) DEFAULT NULL, events_original_name VARCHAR(255) DEFAULT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('COMMENT ON COLUMN event.start_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN event.end_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN event.update_at IS \'(DC2Type:datetime_immutable)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('DROP TABLE event'); + } +} diff --git a/src/Controller/Admin/AdminController.php b/src/Controller/Admin/AdminController.php index 1764e90..9e03cd1 100644 --- a/src/Controller/Admin/AdminController.php +++ b/src/Controller/Admin/AdminController.php @@ -14,17 +14,21 @@ use App\Entity\Ag\MainMember; use App\Entity\Ag\MainOrder; use App\Entity\Ag\MainSigned; use App\Entity\Ag\MainVote; +use App\Entity\Event; use App\Entity\Members; use App\Entity\MembersCotisations; use App\Entity\Products; +use App\Form\EventType; use App\Form\MembersType; use App\Form\ProductsType; use App\Form\RequestPasswordConfirmType; use App\Form\RequestPasswordRequestType; use App\Repository\Ag\MainRepository; +use App\Repository\EventRepository; use App\Repository\MembersCotisationsRepository; use App\Repository\MembersRepository; use App\Repository\ProductsRepository; +use App\Service\Events\AdvertEvent; use App\Service\Mailer\Mailer; use App\Service\Payments\PaymentClient; use App\Service\Pdf\AgAdh; @@ -242,9 +246,43 @@ class AdminController extends AbstractController } #[Route(path: '/admin/events', name: 'admin_events', options: ['sitemap' => false], methods: ['GET'])] - public function adminEvents(): Response + public function adminEvents(EventRepository $eventRepository): Response { - return $this->render('admin/dashboard.twig', [ + return $this->render('admin/events.twig', [ + 'events' => $eventRepository->findBy([],['id' => 'DESC']), + ]); + } + #[Route(path: '/admin/events/delete', name: 'admin_events_delete', options: ['sitemap' => false], methods: ['GET','POST'])] + public function adminEventDelete(?Event $event,EntityManagerInterface $entityManager): Response + { + + } + #[Route(path: '/admin/events/add', name: 'admin_events_create', options: ['sitemap' => false], methods: ['GET','POST'])] + #[Route(path: '/admin/events/{id}', name: 'admin_events_edit', options: ['sitemap' => false], methods: ['GET','POST'])] + public function adminEventAdd(?Event $event,Request $request,EntityManagerInterface $entityManager,EventDispatcherInterface $eventDispatcher): Response + { + $isNew = false; + if(is_null($event)) { + $event = new Event(); + $isNew = true; + } + $form = $this->createForm(EventType::class,$event); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $event->setAffiche($request->files->all()['event']['affiche']); + $event->setUpdateAt(new \DateTimeImmutable('now')); + if($isNew) { + $sendEvent = new AdvertEvent($event); + $eventDispatcher->dispatch($sendEvent); + } + $entityManager->persist($event); + $entityManager->flush(); + + return $this->redirectToRoute('admin_events'); + } + return $this->render('admin/events/add.twig', [ + 'form' => $form->createView(), + 'event' => $event ]); } diff --git a/src/Controller/EventsController.php b/src/Controller/EventsController.php index 18cfc95..1eb8ee7 100644 --- a/src/Controller/EventsController.php +++ b/src/Controller/EventsController.php @@ -4,8 +4,10 @@ namespace App\Controller; use App\Entity\Account; use App\Entity\AccountResetPasswordRequest; +use App\Entity\Event; use App\Form\RequestPasswordConfirmType; use App\Form\RequestPasswordRequestType; +use App\Repository\EventRepository; use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent; use App\Service\ResetPassword\Event\ResetPasswordEvent; use Doctrine\ORM\EntityManagerInterface; @@ -23,17 +25,21 @@ class EventsController extends AbstractController { #[Route(path: '/events', name: 'app_events', options: ['sitemap' => true], methods: ['GET'])] - public function index(): Response + public function index(EventRepository $eventRepository): Response { return $this->render('event.twig',[ - 'events' => [ - - ] + 'events' => $eventRepository->findBy([],['startAt' => 'DESC']), ]); } #[Route(path: '/events/{id}', name: 'app_event_details', options: ['sitemap' => false], methods: ['GET'])] - public function eventDetails(): Response + public function eventDetails(?Event $event): Response { + if(is_null($event)) { + return $this->redirectToRoute('app_events'); + } + return $this->render('event_view.twig',[ + 'event' => $event, + ]); } } diff --git a/src/Entity/Event.php b/src/Entity/Event.php new file mode 100644 index 0000000..88ee93b --- /dev/null +++ b/src/Entity/Event.php @@ -0,0 +1,226 @@ +id; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function setTitle(string $title): static + { + $this->title = $title; + + return $this; + } + + public function getStartAt(): ?\DateTimeImmutable + { + return $this->startAt; + } + + public function setStartAt(\DateTimeImmutable $startAt): static + { + $this->startAt = $startAt; + + return $this; + } + + public function getEndAt(): ?\DateTimeImmutable + { + return $this->endAt; + } + + public function setEndAt(\DateTimeImmutable $endAt): static + { + $this->endAt = $endAt; + + return $this; + } + + public function getLocation(): ?string + { + return $this->location; + } + + public function setLocation(string $location): static + { + $this->location = $location; + + return $this; + } + + public function getOrganizer(): ?string + { + return $this->organizer; + } + + public function setOrganizer(string $organizer): static + { + $this->organizer = $organizer; + + return $this; + } + + /** + * @return \DateTimeImmutable|null + */ + public function getUpdateAt(): ?\DateTimeImmutable + { + return $this->updateAt; + } + + /** + * @return File|null + */ + public function getAffiche(): ?File + { + return $this->affiche; + } + + /** + * @return array|null + */ + public function getEventsDimensions(): ?array + { + return $this->eventsDimensions; + } + + /** + * @return string|null + */ + public function getEventsFileName(): ?string + { + return $this->eventsFileName; + } + + /** + * @return string|null + */ + public function getEventsMineType(): ?string + { + return $this->eventsMineType; + } + + /** + * @return string|null + */ + public function getEventsOriginalName(): ?string + { + return $this->eventsOriginalName; + } + + /** + * @return string|null + */ + public function getEventsSize(): ?string + { + return $this->eventsSize; + } + + /** + * @param \DateTimeImmutable|null $updateAt + */ + public function setUpdateAt(?\DateTimeImmutable $updateAt): void + { + $this->updateAt = $updateAt; + } + + /** + * @param File|null $affiche + */ + public function setAffiche(?File $affiche): void + { + $this->affiche = $affiche; + } + + /** + * @param array|null $eventsDimensions + */ + public function setEventsDimensions(?array $eventsDimensions): void + { + $this->eventsDimensions = $eventsDimensions; + } + + /** + * @param string|null $eventsFileName + */ + public function setEventsFileName(?string $eventsFileName): void + { + $this->eventsFileName = $eventsFileName; + } + + /** + * @param string|null $eventsMineType + */ + public function setEventsMineType(?string $eventsMineType): void + { + $this->eventsMineType = $eventsMineType; + } + + /** + * @param string|null $eventsOriginalName + */ + public function setEventsOriginalName(?string $eventsOriginalName): void + { + $this->eventsOriginalName = $eventsOriginalName; + } + + /** + * @param string|null $eventsSize + */ + public function setEventsSize(?string $eventsSize): void + { + $this->eventsSize = $eventsSize; + } +} diff --git a/src/EventSubscriber/SitemapSubscriber.php b/src/EventSubscriber/SitemapSubscriber.php index 0b6e2ef..d39f47b 100644 --- a/src/EventSubscriber/SitemapSubscriber.php +++ b/src/EventSubscriber/SitemapSubscriber.php @@ -2,6 +2,7 @@ namespace App\EventSubscriber; +use App\Repository\EventRepository; use App\Repository\ProductsRepository; use Cocur\Slugify\Slugify; use Liip\ImagineBundle\Imagine\Cache\CacheManager; @@ -16,7 +17,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; #[AsEventListener(event: SitemapPopulateEvent::class, method: 'onSitemapPopulate', priority: 10)] class SitemapSubscriber { - public function __construct(private readonly ProductsRepository $productsRepository,private CacheManager $cacheManager) + public function __construct(private readonly EventRepository $eventRepository,private readonly ProductsRepository $productsRepository,private CacheManager $cacheManager) { } @@ -116,6 +117,17 @@ class SitemapSubscriber $urlContainer->addUrl($decoratedUrlAbout, 'default'); $s = new Slugify(); + foreach ($this->eventRepository->findAll() as $eventItem) { + $urlAbout = new UrlConcrete($urlGenerator->generate('app_event_details', ['id'=>$eventItem->getid()], UrlGeneratorInterface::ABSOLUTE_URL)); + $decoratedUrlAbout = new GoogleImageUrlDecorator($urlAbout); + $decoratedUrlAbout->addImage(new GoogleImage($this->cacheManager->resolve('assets/images/logo.jpg','webp'))); + $decoratedUrlAbout->addImage(new GoogleImage($this->cacheManager->resolve($eventItem->getAffiche(),'webp'))); + $decoratedUrlAbout = new GoogleMultilangUrlDecorator($decoratedUrlAbout); + foreach ($langs as $lang) { + $decoratedUrlAbout->addLink($urlGenerator->generate('app_event_details',['id'=>$eventItem->getid()], UrlGeneratorInterface::ABSOLUTE_URL), $lang); + } + $urlContainer->addUrl($decoratedUrlAbout, 'events'); + } foreach ($this->productsRepository->findAll() as $product) { $slug = $s->slugify($product->getName()."-".$product->getId()); $urlAbout = new UrlConcrete($urlGenerator->generate('app_product_show', ['slug'=>$slug], UrlGeneratorInterface::ABSOLUTE_URL)); diff --git a/src/Form/EventType.php b/src/Form/EventType.php new file mode 100644 index 0000000..80b3533 --- /dev/null +++ b/src/Form/EventType.php @@ -0,0 +1,62 @@ +add('affiche', FileType::class, [ // Renommé pour plus de clarté + 'label' => 'Affiche de l\'événement (Max 2Mo)', + 'required' => false, + 'mapped' => false, + 'attr' => [ + 'placeholder' => 'Choisir un fichier...', + ] + ]) + ->add('title', TextType::class, [ + 'label' => 'Titre', + 'required' => true, + ]) + ->add('location', TextType::class, [ + 'label' => 'Location', + 'required' => true, + ]) + ->add('organizer', TextType::class, [ + 'label' => 'Organisateur', + 'required' => true, + ]) + ->add('startAt',DateType::class,[ + 'label' => 'Date de début', // Correction du libellé + 'required' => true, + 'widget' => 'single_text', // Affiche un champ de date simple au lieu d'une liste déroulante + 'input' => 'datetime', + ]) + ->add('endAt',DateType::class,[ + 'label' => 'Date de rejoint', // Correction du libellé + 'required' => true, + 'widget' => 'single_text', // Affiche un champ de date simple au lieu d'une liste déroulante + 'input' => 'datetime', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Event::class, + ]); + } +} diff --git a/src/Repository/EventRepository.php b/src/Repository/EventRepository.php new file mode 100644 index 0000000..ec63e8e --- /dev/null +++ b/src/Repository/EventRepository.php @@ -0,0 +1,43 @@ + + */ +class EventRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Event::class); + } + + // /** + // * @return Event[] Returns an array of Event objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('e') + // ->andWhere('e.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('e.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?Event + // { + // return $this->createQueryBuilder('e') + // ->andWhere('e.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/src/Service/Events/AdvertEvent.php b/src/Service/Events/AdvertEvent.php new file mode 100644 index 0000000..4e0c23a --- /dev/null +++ b/src/Service/Events/AdvertEvent.php @@ -0,0 +1,23 @@ +event = $event; + } + + /** + * @return Event + */ + public function getEvent(): Event + { + return $this->event; + } +} diff --git a/src/Service/Events/EventSubscriber.php b/src/Service/Events/EventSubscriber.php new file mode 100644 index 0000000..b22200e --- /dev/null +++ b/src/Service/Events/EventSubscriber.php @@ -0,0 +1,34 @@ +getEvent(); + foreach ($this->membersRepository->findAll() as $member) { + $this->mailer->send($member->getEmail(),$member->getPseudo(),"[E-Cosplay] - Nouveaux événement","mails/event/new.twig",[ + 'event' => $event, + 'url' => $this->urlGenerator->generate('app_event_details',['id'=>$event->getId()],UrlGeneratorInterface::ABSOLUTE_URL), + ]); + } + + } +} diff --git a/templates/admin/events.twig b/templates/admin/events.twig new file mode 100644 index 0000000..0b71482 --- /dev/null +++ b/templates/admin/events.twig @@ -0,0 +1,104 @@ +{% extends 'admin/base.twig' %} + +{% block title 'Événement(s)' %} +{% block page_title 'Liste des Événements' %} + +{% block body %} + + + +
+
+ +

Gestion des Événements

+ + + + Créer un événement + +
+ + + +
+ {% if events is empty %} + +
+ Aucun événement trouvé. Commencez par en créer un ! +
+ {% else %} +
+ + + + + + + + + + + + + + + + {% for event in events %} + + + + + + + + + + + + + {% endfor %} + +
+ Titre + + Début + + Actions +
+ {{ event.title }} + + {{ event.startAt|date('d/m/Y') }} + + + Modifier + + +
+ + +
+
+
+ {% endif %} +
+ + +
+{% endblock %} diff --git a/templates/admin/events/add.twig b/templates/admin/events/add.twig new file mode 100644 index 0000000..ca00601 --- /dev/null +++ b/templates/admin/events/add.twig @@ -0,0 +1,171 @@ +{% extends 'admin/base.twig' %} + +{% block title %}Ajouter/Éditer un événement{% endblock %} +{% block page_title %} + {{ form.vars.value.id ? 'Éditer l\' événement: ' ~ form.vars.value.title : 'Créer un nouveau événement' }} +{% endblock %} + + +{% block body %} + {% form_theme form 'form_admin.twig' %} + + + +
+
+ +

{{ form.vars.value.id ? 'Éditer l\' événement: ' ~ form.vars.value.title : 'Créer un nouveau événement' }}

+ + {{ form_start(form, {'attr': {'class': 'space-y-6'}}) }} + + {% set event = form.vars.data %} + + + {% set input_classes = 'w-full px-4 py-3 border border-gray-600 rounded-lg bg-gray-700 text-gray-100 placeholder-gray-400 focus:ring-indigo-500 focus:border-indigo-500 transition duration-150' %} + {% set label_classes = 'text-white block text-sm font-medium text-gray-100 mb-1' %} + + +
+ {{ form_row(form.title, { + 'label_attr': {'class': label_classes}, + 'attr': {'class': input_classes} + }) }} +
+ + +
+ {{ form_row(form.location, { + 'label_attr': {'class': label_classes}, + 'attr': {'class': input_classes} + }) }} +
+ + +
+ +
+ {{ form_row(form.startAt, { + 'label_attr': {'class': label_classes}, + 'attr': {'class': input_classes} + }) }} +
+ + +
+ {{ form_row(form.endAt, { + 'label_attr': {'class': label_classes}, + 'attr': {'class': input_classes} + }) }} +
+
+ + +
+ {{ form_row(form.organizer, { + 'label_attr': {'class': label_classes}, + 'attr': {'class': input_classes} + }) }} +
+ + {# --- DÉBUT : CHAMP D'UPLOAD D'IMAGE STYLISÉ (Dark Mode) --- #} + {# --- SECTION IMAGE DE PROFIL / UPLOAD --- #} +

+ Affiche +

+ +
+ + {# Zone cliquable pour l'image existante, le placeholder ou la prévisualisation #} + + + {# Champ de fichier réel (caché) #} + {{ form_widget(form.affiche, {'attr': {'class': 'sr-only'}}) }} + +
+

+ Sélectionnez une nouvelle affiche. Le fichier actuel sera remplacé. (Max 2Mo). +

+ {# Affichage des erreurs spécifiques au champ image #} + {{ form_errors(form.affiche) }} +
+ +
+ {# --- FIN : CHAMP D'UPLOAD D'IMAGE STYLISÉ --- #} + + +
+ +
+ + {{ form_end(form) }} +
+ + +
+ +{% endblock %} diff --git a/templates/event.twig b/templates/event.twig index db6743a..b5a8787 100644 --- a/templates/event.twig +++ b/templates/event.twig @@ -7,23 +7,23 @@ {% block breadcrumb_schema %} {% endblock %} @@ -38,53 +38,73 @@ {% if events is defined and events is not empty %}
{% for event in events %} -
-
- {# Event Title #} -

{{ event.title }}

+
-
+ {# --- AJOUT DE L'AFFICHE (IMAGE) --- #} + {% set imageUrl = event.eventsFileName ? vich_uploader_asset(event, 'affiche') : null %} - {# Date Block (Start Date / End Date) #} -

- -

- {{ 'events.list.date_label'|trans|default('Date') }}: -
- {{ 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 %} -
-
-

- - {# Location Block #} -

- -

- {{ 'events.list.location_label'|trans|default('Location') }}: -
{{ event.location }}
-
-

- - {# Organizer Block #} -

- -

- {{ 'events.list.organizer_label'|trans|default('Organizer') }}: -
{{ event.organizer }}
-
-

+ {% if imageUrl %} +
+ Affiche de l'événement {{ event.title }}
-
+ {% else %} + {# Placeholder si aucune image n'est disponible #} +
+ +
+ {% endif %} + {# --- FIN AJOUT DE L'AFFICHE --- #} - {# Details Link (assuming an 'id' or slug is available) #} - - {{ 'events.list.details_button'|trans|default('View Details') }} - +
+
+ {# Event Title #} +

{{ event.title }}

+ +
+ + {# Date Block (Start Date / End Date) #} +

+ +

+ {{ 'events.list.date_label'|trans|default('Date') }}: +
+ {{ event.startAt|date('d/m/Y H:i') }} + {% if event.startAt|date('Ymd') != event.endAt|date('Ymd') %} + - {{ event.endAt|date('d/m/Y H:i') }} + {% else %} + - {{ event.endAt|date('H:i') }} + {% endif %} +
+
+

+ + {# Location Block #} +

+ +

+ {{ 'events.list.location_label'|trans|default('Location') }}: +
{{ event.location }}
+
+

+ + {# Organizer Block #} +

+ +

+ {{ 'events.list.organizer_label'|trans|default('Organizer') }}: +
{{ event.organizer }}
+
+

+
+
+ + {# Details Link (assuming an 'id' or slug is available) #} + + {{ 'events.list.details_button'|trans|default('View Details') }} + +
{% endfor %}
@@ -92,10 +112,10 @@ {# Fallback if no events are found (repurposing the original styling) #}
- - {# Icon: Calendar with an X #} - - + + {# Icon: Calendar with an X #} + +

{{ 'events.no_events_title'|trans|default('No Upcoming Events') }} @@ -113,4 +133,6 @@ {% endif %}

+ + {% endblock %} diff --git a/templates/event_view.twig b/templates/event_view.twig new file mode 100644 index 0000000..b102e75 --- /dev/null +++ b/templates/event_view.twig @@ -0,0 +1,116 @@ +{% extends 'base.twig' %} + +{% block title %}{{ event.title }}{% endblock %} +{% block meta_description %}{{ event.title }}{% endblock %} + +{% block canonical_url %}{% endblock %} +{% block breadcrumb_schema %} + +{% endblock %} + +{% block body %} +
+
+ + {% set imageUrl = event.eventsFileName ? vich_uploader_asset(event, 'affiche') : null %} + + {# Image / Affiche de l'événement #} + {% if imageUrl %} +
+ Affiche de l'événement {{ event.title }} +
+ {% endif %} + +
+ + {# Titre principal #} +

+ {{ event.title }} +

+ + {# Détails clés (Date, Lieu, Organisateur) #} +
+ + {# Date Block #} +
+ +
+

{{ 'events.details.date'|trans|default('Date') }}

+

+ {{ event.startAt|date('d/m/Y') }} + {% if event.startAt|date('Ymd') != event.endAt|date('Ymd') %} + - {{ event.endAt|date('d/m/Y') }} + {% else %} + - {{ event.endAt|date('H:i') }} + {% endif %} +

+
+
+ + {# Location Block #} +
+ +
+

{{ 'events.details.location'|trans|default('Lieu') }}

+

{{ event.location }}

+
+
+ + {# Organizer Block #} +
+ +
+

{{ 'events.details.organizer'|trans|default('Organisateur') }}

+

{{ event.organizer }}

+
+
+
+ + {# Description #} + {% if event.description is defined and event.description is not empty %} +

+ {{ 'events.details.description_title'|trans|default('Description') }} +

+
+ {{ event.description|raw }} {# Assuming description is HTML/Markdown content #} +
+ {% endif %} + + {# Bouton de retour #} + + + {{ 'events.details.back_to_list'|trans|default('Retour à la liste des événements') }} + +
+
+
+ + +{% endblock %} diff --git a/templates/mails/event/new.twig b/templates/mails/event/new.twig new file mode 100644 index 0000000..6de5315 --- /dev/null +++ b/templates/mails/event/new.twig @@ -0,0 +1,75 @@ +{% extends 'mails/base.twig' %} + +{% block subject %} + Nouveaux événement : {{ datas.event.title }} +{% endblock %} + +{% block content %} + + + + Découvrez notre nouvel événement ! + + + Nous sommes ravis de vous annoncer la création d'un nouvel événement. Voici les détails : + + + + + {# Détails de l'événement #} + + + + + Titre de l'événement : + + + {{ datas.event.title }} + + + + + {# Organisateur #} + + Organisateur : + + + {{ datas.event.organizer }} + + + {# Lieu #} + + Lieu : + + + {{ datas.event.location }} + + + {# Dates #} + + + + Début :
+ {{ datas.event.startAt|date('d/m/Y') }} + + + Fin :
+ {{ datas.event.endAt|date('d/m/Y') }} + + +
+ + + + {# Appel à l'action (CTA) vers l'URL publique #} + + Voir les détails de l'événement + + +
+ + +
+{% endblock %} diff --git a/templates/txt-mails/event/new.twig b/templates/txt-mails/event/new.twig new file mode 100644 index 0000000..bdc5e34 --- /dev/null +++ b/templates/txt-mails/event/new.twig @@ -0,0 +1,17 @@ +Nouveaux événement : {{ datas.event.title }} + +Découvrez notre nouvel événement ! + +Nous sommes ravis de vous annoncer la création d'un nouvel événement. Voici les détails : + +Titre de l'événement : {{ datas.event.title }} +Organisateur : {{ datas.event.organizer }} +Lieu : {{ datas.event.location }} +Début : {{ datas.event.startAt|date('d/m/Y') }} +Fin : {{ datas.event.endAt|date('d/m/Y') }} + +Voir les détails de l'événement : +{{ datas.url }} + +À très vite, +L'équipe [Nom de votre organisation] diff --git a/translations/messages.cn.yaml b/translations/messages.cn.yaml index 3b16576..1be98d1 100644 --- a/translations/messages.cn.yaml +++ b/translations/messages.cn.yaml @@ -670,3 +670,12 @@ adh_page_validate: footer_action_title: "我们的行动" footer_realise: '导演是' Documents: '文件' +list_main_title: 即将举行的活动 +events.list.date_label: 日期 +events.list.location_label: 地点 +events.list.organizer_label: 主办方 +events.list.details_button: 查看详情 +events.details.date: 日期 +events.details.location: 地点 +events.details.organizer: 主办方 +events.details.back_to_list: 返回活动列表 diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 74f6e62..cc08e95 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -738,3 +738,14 @@ adh_page_validate: footer_action_title: "Our actions" footer_realise: 'Directed by' Documents: 'Documents' + +list_main_title: Upcoming Events +events.list.date_label: Date +events.list.location_label: Location +events.list.organizer_label: Organizer +events.list.details_button: View Details + +events.details.date: Date +events.details.location: Location +events.details.organizer: Organizer +events.details.back_to_list: Back to Events List diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index a9c2ede..1ece174 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -680,3 +680,16 @@ adh_page_validate: thanks: "Merci pour votre participation !" footer_realise: 'Réalisé par' Documents: 'Documents' + + +list_main_title: Événements à Venir +events.list.date_label: Date +events.list.location_label: Lieu +events.list.organizer_label: Organisateur +events.list.details_button: Voir les détails + + +events.details.date: Date +events.details.location: Lieu +events.details.organizer: Organisateur +events.details.back_to_list: Retour à la liste des événements