des trucs

This commit is contained in:
mepiphana2023
2024-11-28 10:47:01 +01:00
parent 921e7bfdea
commit 0c6ac2fa20
17 changed files with 174 additions and 48 deletions

View File

@@ -1,4 +1,5 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,600;1,400;1,600&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,600;1,400;1,600&display=swap');
@import "button.css";
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;

91
assets/styles/button.css Normal file
View File

@@ -0,0 +1,91 @@
.btnPrimary {
@apply bg-[#2a8d57] text-white font-bold py-2 px-4 border-b-4 rounded transition-all duration-300 ease-in-out;
/* Bordure */
border-color: #1e7a43;
/* Survol */
&:hover {
@apply bg-[#1e7a43] border-[#155d2e];
}
/* Clique (État actif) */
&:active {
@apply bg-[#1b6b38] border-[#155d2e];
}
/* Focus (État focus) */
&:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(42, 141, 87, 0.5);
}
}
.btnSecondary {
@apply bg-[#2f4858] text-white font-bold py-2 px-4 border-b-4 rounded transition-all duration-300 ease-in-out;
/* Bordure */
border-color: #1e3c46;
/* Survol */
&:hover {
@apply bg-[#1e3c46] border-[#16323a];
}
/* Clique (État actif) */
&:active {
@apply bg-[#193d49] border-[#16323a];
}
/* Focus (État focus) */
&:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(47, 72, 88, 0.5);
}
}
.btnThird {
@apply bg-[#c0ab4d] text-white font-bold py-2 px-4 border-b-4 rounded transition-all duration-300 ease-in-out;
/* Bordure */
border-color: #b0a139;
/* Survol */
&:hover {
@apply bg-[#b0a139] border-[#9a8b2b];
}
/* Clique (État actif) */
&:active {
@apply bg-[#9a8b2b] border-[#6f6a1c];
}
/* Focus (État focus) */
&:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(192, 171, 77, 0.5);
}
}
.btnAnnule {
@apply bg-[#d54f45] text-white font-bold py-2 px-4 border-b-4 rounded transition-all duration-300 ease-in-out;
/* Bordure */
border-color: #a73a2d;
/* Survol */
&:hover {
@apply bg-[#a73a2d] border-[#8b2d1e];
}
/* Clique (État actif) */
&:active {
@apply bg-[#90271e] border-[#8b2d1e];
}
/* Focus (État focus) */
&:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(213, 79, 69, 0.5);
}
}

View File

@@ -28,5 +28,12 @@ services:
arguments: arguments:
$targetDirectory: '../public/upload/image/profile/' $targetDirectory: '../public/upload/image/profile/'
App\EventListener\UserProfileListener:
arguments:
- '@security.token_storage'
- '@twig'
tags:
- { name: 'kernel.event_subscriber' }
# add more service definitions when explicit configuration is needed # add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones # please note that last definitions always *replace* previous ones

View File

@@ -48,12 +48,9 @@ class AdminController extends AbstractController
#[Route('/admin/user', name: 'app_adminUser')] #[Route('/admin/user', name: 'app_adminUser')]
public function adminUser(TokenStorageInterface $tokenStorage): Response public function adminUser(TokenStorageInterface $tokenStorage): Response
{ {
$token = $tokenStorage->getToken();
$userConnect = $token?->getUser();
$participants = $this->participantRepository->findAll(); $participants = $this->participantRepository->findAll();
$sites = $this->siteRepository->findAll(); $sites = $this->siteRepository->findAll();
return $this->render('admin/user.html.twig', [ return $this->render('admin/user.html.twig', [
'profile' => $userConnect,
'participants' => $participants, 'participants' => $participants,
'sites' => $sites, 'sites' => $sites,
'controller_name' => 'AdminController', 'controller_name' => 'AdminController',

View File

@@ -19,8 +19,6 @@ class MainController extends AbstractController
{ {
// Récupérer les 5 dernières sorties // Récupérer les 5 dernières sorties
$latestSorties = $sortieRepository->findBy([], ['dateHeureDebut' => 'DESC'], 5); $latestSorties = $sortieRepository->findBy([], ['dateHeureDebut' => 'DESC'], 5);
$token = $tokenStorage->getToken();
$userConnect = $token?->getUser();
$dateLimit = new \DateTime(); $dateLimit = new \DateTime();
$dateLimit->modify('-30 days'); // Date limite = il y a 30 jours $dateLimit->modify('-30 days'); // Date limite = il y a 30 jours
@@ -35,7 +33,6 @@ class MainController extends AbstractController
return $this->render('main/home.html.twig', [ return $this->render('main/home.html.twig', [
'lastSorties' => $latestSorties, 'lastSorties' => $latestSorties,
'profile' => $userConnect,
'pastEvents' => $pastEvents, 'pastEvents' => $pastEvents,
]); ]);
} }

View File

@@ -25,13 +25,9 @@ class SortieController extends AbstractController
{ {
#[Route('/sortie/liste', name: 'list', methods: ['GET'])] #[Route('/sortie/liste', name: 'list', methods: ['GET'])]
public function index( public function index(
TokenStorageInterface $tokenStorage,
SortieRepository $sortieRepository, SortieRepository $sortieRepository,
Request $request Request $request
): Response { ): Response {
$token = $tokenStorage->getToken();
$userConnect = $token?->getUser();
// Récupérer les paramètres de filtre // Récupérer les paramètres de filtre
$search = $request->query->get('search', ''); $search = $request->query->get('search', '');
$siteId = $request->query->get('site', ''); $siteId = $request->query->get('site', '');
@@ -46,7 +42,6 @@ class SortieController extends AbstractController
$sorties = $sortieRepository->findWithFilters($search, $siteId, $startDate, $endDate, $organisateur, $inscrit, $nonInscrit, $passees, $userConnect); $sorties = $sortieRepository->findWithFilters($search, $siteId, $startDate, $endDate, $organisateur, $inscrit, $nonInscrit, $passees, $userConnect);
return $this->render('sortie/list.html.twig', [ return $this->render('sortie/list.html.twig', [
'profile' => $userConnect,
'sorties' => $sorties, 'sorties' => $sorties,
'sites' => $sortieRepository->findAllSites(), 'sites' => $sortieRepository->findAllSites(),
]); ]);
@@ -62,7 +57,6 @@ class SortieController extends AbstractController
ParticipantRepository $participantRepository, ParticipantRepository $participantRepository,
EtatRepository $etatRepository EtatRepository $etatRepository
): Response { ): Response {
// Vérifier si l'utilisateur est connecté
$userConnect = $tokenStorage->getToken()?->getUser(); $userConnect = $tokenStorage->getToken()?->getUser();
if (!$userConnect) { if (!$userConnect) {
$this->addFlash('error', 'Vous devez être connecté pour créer une sortie.'); $this->addFlash('error', 'Vous devez être connecté pour créer une sortie.');
@@ -114,7 +108,6 @@ class SortieController extends AbstractController
} }
return $this->render('sortie/create.html.twig', [ return $this->render('sortie/create.html.twig', [
'profile' => $userConnect,
'form' => $form->createView(), 'form' => $form->createView(),
'sortie' => $sortie, 'sortie' => $sortie,
]); ]);
@@ -124,7 +117,6 @@ class SortieController extends AbstractController
public function view( public function view(
string $id, string $id,
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
TokenStorageInterface $tokenStorage
): Response { ): Response {
$sortie = $entityManager->getRepository(Sortie::class)->find($id); $sortie = $entityManager->getRepository(Sortie::class)->find($id);
if (!$sortie) { if (!$sortie) {
@@ -146,7 +138,6 @@ class SortieController extends AbstractController
return $this->render('sortie/view.html.twig', [ return $this->render('sortie/view.html.twig', [
'sortie' => $sortie, 'sortie' => $sortie,
'profile' => $tokenStorage->getToken()?->getUser(),
]); ]);
} }

View File

@@ -0,0 +1,42 @@
<?php
namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Twig\Environment;
class UserProfileListener implements EventSubscriberInterface
{
private $tokenStorage;
private $twig;
public function __construct(TokenStorageInterface $tokenStorage, Environment $twig)
{
$this->tokenStorage = $tokenStorage;
$this->twig = $twig;
}
public function onKernelRequest(RequestEvent $event)
{
$token = $this->tokenStorage->getToken();
// Vérifie si l'utilisateur est connecté
if ($token && $token->getUser()) {
$profile = $token->getUser(); // Récupère l'utilisateur connecté
$event->getRequest()->attributes->set('profile', $profile);
// Ajoute 'profile' à toutes les vues Twig
$this->twig->addGlobal('profile', $profile);
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
];
}
}

View File

@@ -14,7 +14,7 @@
<!-- Actions: Ajouter --> <!-- Actions: Ajouter -->
<div class="mb-4"> <div class="mb-4">
<!-- Bouton pour ouvrir la modale --> <!-- Bouton pour ouvrir la modale -->
<button id="openModal" class="inline-block bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700"> <button id="openModal" class="btnPrimary">
Ajouter un site Ajouter un site
</button> </button>
</div> </div>

View File

@@ -14,7 +14,7 @@
<div class="flex flex-row mb-4 justify-between"> <div class="flex flex-row mb-4 justify-between">
<button <button
id="openModal" id="openModal"
class="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700 items-end justify-end"> class="btnPrimary">
Ajouter un utilisateur Ajouter un utilisateur
</button> </button>
</div> </div>
@@ -24,10 +24,10 @@
<div class="flex flex-row"> <div class="flex flex-row">
<button <button
id="openModalCsv" type="button" id="openModalCsv" type="button"
class="bg-green-500 text-white mb-4 mr-4 px-4 py-2 rounded hover:bg-green-600"> class="btnSecondary">
Importer CSV Importer CSV
</button> </button>
<button type="submit" class="bg-blue-500 text-white px-4 py-2 mb-4 rounded hover:bg-blue-600"> <button type="submit" class="btnThird">
<a href="{{ path('participant_export') }}">Exporter CSV</a> <a href="{{ path('participant_export') }}">Exporter CSV</a>
</button> </button>
</div> </div>
@@ -177,7 +177,7 @@
</div> </div>
<p>* Champ obligatoire</p> <p>* Champ obligatoire</p>
<div class="flex justify-end"> <div class="flex justify-end">
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700">Ajouter</button> <button type="submit" class="btnPrimary">Ajouter</button>
<button type="button" id="closeModal" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button> <button type="button" id="closeModal" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button>
</div> </div>
</form> </form>
@@ -205,7 +205,7 @@
<div class="flex flex-row"> <div class="flex flex-row">
<button <button
type="submit" type="submit"
class="bg-green-500 text-white mr-4 px-4 py-2 rounded hover:bg-green-600"> class="btnSecondary">
Importer CSV Importer CSV
</button> </button>
<button type="button" id="closeModalCsv" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button> <button type="button" id="closeModalCsv" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button>

View File

@@ -1,4 +1,5 @@
{% extends 'main/base.html.twig' %} {% extends 'main/base.html.twig' %}
{% block head %} {% block head %}
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
@@ -16,22 +17,24 @@
<form action="{{ path('app_login') }}" method="post"> <form action="{{ path('app_login') }}" method="post">
<label class="text-gray-700 font-bold" for="username">Email ou pseudo</label> <label class="text-gray-700 font-bold" for="username">Email ou pseudo</label>
<input class="w-full mb-4 px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" placeholder="Adresse e-mail ou pseudo" type="text" value="{{ last_username }}" name="username" id="username" autocomplete="email" required autofocus> <input class="w-full mb-4 px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" placeholder="Adresse e-mail ou pseudo" type="text" value="{{ last_username }}" name="username" id="username" autocomplete="email" required autofocus>
<div class="mb-4"> <div class="mb-4">
<label class="text-gray-700 font-bold" for="password">Mot de passe</label> <label class="text-gray-700 font-bold" for="password">Mot de passe</label>
<input class="w-full mb-2 px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" placeholder="Mot de passe" type="password" name="password" id="password" autocomplete="current-password" required> <input class="w-full mb-2 px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" placeholder="Mot de passe" type="password" name="password" id="password" autocomplete="current-password" required>
<a id="openModal" class="text-blue-500 text-sm hover:underline">Mot de passe oublié ?</a> <a id="openModal" class="text-blue-500 text-sm hover:underline">Mot de passe oublié ?</a>
</div> </div>
<label> <label>
<input type="checkbox" name="_remember_me" checked> <input type="checkbox" name="_remember_me" checked>
Se souvenir de moi Se souvenir de moi
</label> </label>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}" <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
>
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<button class=" text-white font-bold py-2 px-4 border-b-4 btnRegister rounded" type="submit">Se connecter</button> <button class="btnPrimary" type="submit">Se connecter</button>
<a href="{{ path('app_register') }}"> <a href="{{ path('app_register') }}">
<button class=" text-white font-bold py-2 px-4 border-b-4 btnRegister rounded mx-auto" type="button">S'inscrire</button> <button class="btnSecondary" type="button">S'inscrire</button>
</a> </a>
</div> </div>
</form> </form>
@@ -49,8 +52,8 @@
</div> </div>
<div class="flex justify-end"> <div class="flex justify-end">
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700">Envoyer</button> <button type="submit" class="btnPrimary">Envoyer</button>
<button type="button" id="closeModal" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button> <button type="button" id="closeModal" class="btnAnnule ml-2">Annuler</button>
</div> </div>
</form> </form>
</div> </div>
@@ -68,6 +71,5 @@
document.getElementById('resetModal').classList.add('hidden'); document.getElementById('resetModal').classList.add('hidden');
}); });
</script> </script>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -24,7 +24,7 @@
{{ form_row(registrationForm.email) }} {{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.pseudo) }} {{ form_row(registrationForm.pseudo) }}
{{ form_row(registrationForm.plainPassword) }} {{ form_row(registrationForm.plainPassword) }}
<button class="btnRegister text-white font-bold py-2 px-4 border-b-4 rounded mx-auto" type="submit">S'inscrire</button> <button class="btnSecondary" type="submit">S'inscrire</button>
{{ form_end(registrationForm) }} {{ form_end(registrationForm) }}
</div> </div>
</div> </div>

View File

@@ -44,7 +44,7 @@
{{ form_row(formProfile.deleteImage) }} {{ form_row(formProfile.deleteImage) }}
<img class="mx-auto justify-items-center" alt="image de profile" src="{{ asset('/upload/image/profile/' ~ formProfile.vars.value.fileName) }}" height="128" width="128"> <img class="mx-auto justify-items-center" alt="image de profile" src="{{ asset('/upload/image/profile/' ~ formProfile.vars.value.fileName) }}" height="128" width="128">
{% endif %} {% endif %}
<button class="btnRegister text-white font-bold py-2 px-4 border-b-4 rounded mx-auto" type="submit">Actualiser les informations</button> <button class="btnPrimary" type="submit">Actualiser les informations</button>
{{ form_end(formProfile) }} {{ form_end(formProfile) }}
</div> </div>
</div> </div>

View File

@@ -26,7 +26,7 @@
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
<div class="w-full px-4"> <div class="w-full px-4">
<a href="{{ path('profile_edit', {'uuid': app.user.idParticipant}) }}" class="text-slate-700 hover:text-slate-400"> <a href="{{ path('profile_edit', {'uuid': app.user.idParticipant}) }}" class="text-slate-700 hover:text-slate-400">
<button class="bg-green-500 px-4 py-2 rounded hover:bg-green-700"> <button class="btnThird">
Modifier Modifier
</button> </button>
</a> </a>

View File

@@ -110,9 +110,6 @@
</div> </div>
{% endif %} {% endif %}
<button type="button" id="generate-image" class="modern-button mt-2">
Générer une image
</button>
</div> </div>
</div> </div>
@@ -121,10 +118,7 @@
<label for="sortie_lieu">Lieu</label> <label for="sortie_lieu">Lieu</label>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
{{ form_widget(form.lieu, { 'attr': { 'class': 'block w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500', 'id': 'lieu-select' } }) }} {{ form_widget(form.lieu, { 'attr': { 'class': 'block w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500', 'id': 'lieu-select' } }) }}
<button type="button" id="add-lieu-button" class="modern-button"> <button type="button" id="add-lieu-button" class="btnThird">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
Ajouter Ajouter
</button> </button>
</div> </div>
@@ -154,10 +148,10 @@
</div> </div>
<div class="mt-6 flex justify-center space-x-4"> <div class="mt-6 flex justify-center space-x-4">
<button type="submit" name="action" value="save" class="px-6 py-3 bg-green-500 text-white rounded-lg shadow hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-300"> <button type="submit" name="action" value="save" class="btnPrimary">
Enregistrer Enregistrer
</button> </button>
<a href="{{ path('home') }}" class="px-6 py-3 bg-gray-500 text-white rounded-lg shadow hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-300"> <a href="{{ path('home') }}" class="btnAnnule">
Annuler Annuler
</a> </a>
</div> </div>

View File

@@ -71,10 +71,10 @@
</div> </div>
<div class="flex justify-end mt-8 space-x-4"> <div class="flex justify-end mt-8 space-x-4">
<a href="{{ path('sortie_view', { id: sortie.getIdSortie() }) }}" class="px-6 py-3 bg-gray-500 text-white rounded-lg shadow-md hover:bg-gray-600"> <a href="{{ path('sortie_view', { id: sortie.getIdSortie() }) }}" class="btnAnnule">
❌ Annuler ❌ Annuler
</a> </a>
<button type="submit" class="px-6 py-3 bg-blue-500 text-white rounded-lg shadow-md hover:bg-blue-600"> <button type="submit" class="btnPrimary">
💾 Enregistrer 💾 Enregistrer
</button> </button>
</div> </div>

View File

@@ -97,7 +97,7 @@
<!-- Bouton de filtrage --> <!-- Bouton de filtrage -->
<div class="mt-6 flex justify-end"> <div class="mt-6 flex justify-end">
<button type="submit" class="px-6 py-2 bg-blue-500 text-white rounded-md shadow hover:bg-blue-600"> <button type="submit" class="btnPrimary">
🔎 Filtrer 🔎 Filtrer
</button> </button>
</div> </div>

View File

@@ -79,7 +79,7 @@
{% if app.user and sortie.etat.libelle == 'Ouverte' and not sortie.participants.contains(app.user) and date(sortie.dateLimiteInscription) > date() %} {% if app.user and sortie.etat.libelle == 'Ouverte' and not sortie.participants.contains(app.user) and date(sortie.dateLimiteInscription) > date() %}
<form action="{{ path('sortie_inscription', { id: sortie.idSortie }) }}" method="post" class="mt-6"> <form action="{{ path('sortie_inscription', { id: sortie.idSortie }) }}" method="post" class="mt-6">
<button type="submit" class="px-6 py-3 bg-green-500 text-white rounded-md shadow hover:bg-green-600"> <button type="submit" class="btnPrimary">
✅ S'inscrire ✅ S'inscrire
</button> </button>
</form> </form>
@@ -88,7 +88,7 @@
<p class="text-green-600 font-bold">✅ Vous êtes déjà inscrit à cette sortie.</p> <p class="text-green-600 font-bold">✅ Vous êtes déjà inscrit à cette sortie.</p>
{% if sortie.etat.libelle == 'Ouverte' %} {% if sortie.etat.libelle == 'Ouverte' %}
<form action="{{ path('sortie_unsubscribe', { id: sortie.idSortie }) }}" method="post" class="mt-6"> <form action="{{ path('sortie_unsubscribe', { id: sortie.idSortie }) }}" method="post" class="mt-6">
<button type="submit" class="px-6 py-3 bg-red-500 text-white rounded-md shadow hover:bg-red-600"> <button type="submit" class="btnAnnule">
❌ Se désister ❌ Se désister
</button> </button>
</form> </form>
@@ -102,9 +102,13 @@
<button <button
type="button" type="button"
id="open-delete-modal" id="open-delete-modal"
class="px-6 py-3 bg-red-500 text-white rounded-md shadow hover:bg-red-600"> class="btnAnnule">
❌ Annuler la sortie ❌ Annuler la sortie
</button> </button>
<a href="{{ path('sortie_edit', { id: sortie.idSortie }) }}"
class="btnSecondary">
✏️ Modifier la sortie
</a>
{% endif %} {% endif %}
{% if sortie.etat.libelle == 'Créée' %} {% if sortie.etat.libelle == 'Créée' %}
<a href="{{ path('sortie_edit', { id: sortie.idSortie }) }}" <a href="{{ path('sortie_edit', { id: sortie.idSortie }) }}"
@@ -170,7 +174,7 @@
</button> </button>
<button <button
type="submit" type="submit"
class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600"> class="btnAnnule">
Confirmer l'annulation Confirmer l'annulation
</button> </button>
</div> </div>