diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index b07e54d..7b18f42 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -13,8 +13,35 @@ use Symfony\Component\HttpFoundation\Request; class MainController extends AbstractController { + #[Route('/', name: 'home')] - public function index( + public function home(SortieRepository $sortieRepository, TokenStorageInterface $tokenStorage,): Response + { + // Récupérer les 5 dernières sorties + $latestSorties = $sortieRepository->findBy([], ['dateHeureDebut' => 'DESC'], 5); + $token = $tokenStorage->getToken(); + $userConnect = $token?->getUser(); + $dateLimit = new \DateTime(); + $dateLimit->modify('-30 days'); // Date limite = il y a 30 jours + + $pastEvents = $sortieRepository->createQueryBuilder('s') + ->where('s.dateHeureDebut < :now') + ->andWhere('s.dateHeureDebut >= :dateLimit') + ->setParameter('now', new \DateTime()) + ->setParameter('dateLimit', $dateLimit) + ->orderBy('s.dateHeureDebut', 'DESC') + ->getQuery() + ->getResult(); + + return $this->render('main/home.html.twig', [ + 'lastSorties' => $latestSorties, + 'profile' => $userConnect, + 'pastEvents' => $pastEvents, + ]); + } + + #[Route('/dashboard', name: 'dashboard')] + public function dashboard( TokenStorageInterface $tokenStorage, SortieRepository $sortieRepository, Request $request diff --git a/src/Controller/SortieController.php b/src/Controller/SortieController.php index cac9415..f723aa4 100644 --- a/src/Controller/SortieController.php +++ b/src/Controller/SortieController.php @@ -11,16 +11,19 @@ use App\Repository\ParticipantRepository; use App\Repository\SortieRepository; use DateTime; use Doctrine\ORM\EntityManagerInterface; +use OpenAI\Factory; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use OpenAI\Client; #[Route('/sortie', name: 'sortie_')] class SortieController extends AbstractController { - #[Route('/liste', name: 'list', methods: ['GET'])] + #[Route('/sortie/liste', name: 'list', methods: ['GET'])] public function index( TokenStorageInterface $tokenStorage, SortieRepository $sortieRepository, @@ -39,6 +42,7 @@ class SortieController extends AbstractController $nonInscrit = $request->query->get('non_inscrit', false); $passees = $request->query->get('passees', false); + // Recherche par nom de sortie $sorties = $sortieRepository->findWithFilters($search, $siteId, $startDate, $endDate, $organisateur, $inscrit, $nonInscrit, $passees, $userConnect); return $this->render('sortie/list.html.twig', [ @@ -48,6 +52,7 @@ class SortieController extends AbstractController ]); } + #[Route('/creates', name: 'create', methods: ['GET', 'POST'])] public function create( Request $request, @@ -83,8 +88,14 @@ class SortieController extends AbstractController return $this->redirectToRoute('sortie_create'); } + // Gérer l'image (upload) + $imageFile = $form->get('imageFile')->getData(); + if ($imageFile) { + $sortie->setImageFile($imageFile); + } + // Définir les relations et l'état initial - $etat = $etatRepository->findOneBy(['libelle' => 'Ouverte']); + $etat = $etatRepository->findOneBy(['libelle' => 'Créée']); if (!$etat) { $this->addFlash('error', 'Erreur interne : état introuvable.'); return $this->redirectToRoute('sortie_create'); @@ -105,6 +116,7 @@ class SortieController extends AbstractController return $this->render('sortie/create.html.twig', [ 'profile' => $userConnect, 'form' => $form->createView(), + 'sortie' => $sortie, ]); } @@ -267,4 +279,5 @@ class SortieController extends AbstractController $this->addFlash('success', 'La sortie a été annulée avec succès.'); return $this->redirectToRoute('home'); } + } diff --git a/src/Entity/Sortie.php b/src/Entity/Sortie.php index af83f62..bd3fbdf 100644 --- a/src/Entity/Sortie.php +++ b/src/Entity/Sortie.php @@ -7,9 +7,12 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\Validator\Constraints as Assert; +use Vich\UploaderBundle\Mapping\Annotation as Vich; #[ORM\Entity(repositoryClass: SortieRepository::class)] +#[Vich\Uploadable] class Sortie { #[ORM\Id] @@ -66,6 +69,15 @@ class Sortie )] private ?string $motifAnnul = null; + #[ORM\Column(type: 'string', length: 255, nullable: true)] + private ?string $image = null; + + #[Vich\UploadableField(mapping: 'sortie_images', fileNameProperty: 'image')] + private ?File $imageFile = null; + + #[ORM\Column(type: 'datetime', nullable: true)] + private ?\DateTimeInterface $updatedAt = null; + public function __construct() { $this->participants = new ArrayCollection(); @@ -233,4 +245,44 @@ class Sortie return $this; } + + public function getImage(): ?string + { + return $this->image; + } + + public function setImage(?string $image): self + { + $this->image = $image; + + return $this; + } + + public function getImageFile(): ?File + { + return $this->imageFile; + } + + public function setImageFile(?File $imageFile): self + { + $this->imageFile = $imageFile; + + if ($imageFile) { + $this->updatedAt = new \DateTimeImmutable(); + } + + return $this; + } + + public function getUpdatedAt(): ?\DateTimeInterface + { + return $this->updatedAt; + } + + public function setUpdatedAt(?\DateTimeInterface $updatedAt): self + { + $this->updatedAt = $updatedAt; + + return $this; + } } diff --git a/src/Form/SortieType.php b/src/Form/SortieType.php index 0f54912..1c2c355 100644 --- a/src/Form/SortieType.php +++ b/src/Form/SortieType.php @@ -9,6 +9,7 @@ use App\Entity\Site; use App\Entity\Sortie; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\DateType; @@ -16,6 +17,7 @@ use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\File; class SortieType extends AbstractType { @@ -60,6 +62,18 @@ class SortieType extends AbstractType 'placeholder' => 'Sélectionnez un lieu', 'required' => true, 'attr' => ['id' => 'lieu-select'], + ]) + ->add('imageFile', FileType::class, [ + 'label' => 'Image de la sortie', + 'mapped' => false, + 'required' => false, + 'constraints' => [ + new File([ + 'maxSize' => '5M', + 'mimeTypes' => ['image/jpeg', 'image/png'], + 'mimeTypesMessage' => 'Veuillez télécharger une image valide (JPEG ou PNG).', + ]) + ], ]); } diff --git a/tailwind.config.js b/tailwind.config.js index 1ceba2b..5e3db56 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -6,6 +6,13 @@ module.exports = { ], theme: { extend: {}, + screens: { + sm: '640px', // Small screens start at 640px + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px', + }, }, plugins: [], } diff --git a/templates/main/base.html.twig b/templates/main/base.html.twig index 02e5ca9..5ce5586 100644 --- a/templates/main/base.html.twig +++ b/templates/main/base.html.twig @@ -2,6 +2,7 @@
+