des trucs
This commit is contained in:
@@ -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 "button.css";
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
|
||||
91
assets/styles/button.css
Normal file
91
assets/styles/button.css
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -28,5 +28,12 @@ services:
|
||||
arguments:
|
||||
$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
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
||||
@@ -48,12 +48,9 @@ class AdminController extends AbstractController
|
||||
#[Route('/admin/user', name: 'app_adminUser')]
|
||||
public function adminUser(TokenStorageInterface $tokenStorage): Response
|
||||
{
|
||||
$token = $tokenStorage->getToken();
|
||||
$userConnect = $token?->getUser();
|
||||
$participants = $this->participantRepository->findAll();
|
||||
$sites = $this->siteRepository->findAll();
|
||||
return $this->render('admin/user.html.twig', [
|
||||
'profile' => $userConnect,
|
||||
'participants' => $participants,
|
||||
'sites' => $sites,
|
||||
'controller_name' => 'AdminController',
|
||||
|
||||
@@ -19,8 +19,6 @@ class MainController extends AbstractController
|
||||
{
|
||||
// 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
|
||||
|
||||
@@ -35,7 +33,6 @@ class MainController extends AbstractController
|
||||
|
||||
return $this->render('main/home.html.twig', [
|
||||
'lastSorties' => $latestSorties,
|
||||
'profile' => $userConnect,
|
||||
'pastEvents' => $pastEvents,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -25,13 +25,9 @@ class SortieController extends AbstractController
|
||||
{
|
||||
#[Route('/sortie/liste', name: 'list', methods: ['GET'])]
|
||||
public function index(
|
||||
TokenStorageInterface $tokenStorage,
|
||||
SortieRepository $sortieRepository,
|
||||
Request $request
|
||||
): Response {
|
||||
$token = $tokenStorage->getToken();
|
||||
$userConnect = $token?->getUser();
|
||||
|
||||
// Récupérer les paramètres de filtre
|
||||
$search = $request->query->get('search', '');
|
||||
$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);
|
||||
|
||||
return $this->render('sortie/list.html.twig', [
|
||||
'profile' => $userConnect,
|
||||
'sorties' => $sorties,
|
||||
'sites' => $sortieRepository->findAllSites(),
|
||||
]);
|
||||
@@ -62,7 +57,6 @@ class SortieController extends AbstractController
|
||||
ParticipantRepository $participantRepository,
|
||||
EtatRepository $etatRepository
|
||||
): Response {
|
||||
// Vérifier si l'utilisateur est connecté
|
||||
$userConnect = $tokenStorage->getToken()?->getUser();
|
||||
if (!$userConnect) {
|
||||
$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', [
|
||||
'profile' => $userConnect,
|
||||
'form' => $form->createView(),
|
||||
'sortie' => $sortie,
|
||||
]);
|
||||
@@ -124,7 +117,6 @@ class SortieController extends AbstractController
|
||||
public function view(
|
||||
string $id,
|
||||
EntityManagerInterface $entityManager,
|
||||
TokenStorageInterface $tokenStorage
|
||||
): Response {
|
||||
$sortie = $entityManager->getRepository(Sortie::class)->find($id);
|
||||
if (!$sortie) {
|
||||
@@ -146,7 +138,6 @@ class SortieController extends AbstractController
|
||||
|
||||
return $this->render('sortie/view.html.twig', [
|
||||
'sortie' => $sortie,
|
||||
'profile' => $tokenStorage->getToken()?->getUser(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
42
src/EventListener/UserProfileListener.php
Normal file
42
src/EventListener/UserProfileListener.php
Normal 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',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
<!-- Actions: Ajouter -->
|
||||
<div class="mb-4">
|
||||
<!-- 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
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="flex flex-row mb-4 justify-between">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
</div>
|
||||
@@ -24,10 +24,10 @@
|
||||
<div class="flex flex-row">
|
||||
<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
|
||||
</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>
|
||||
</button>
|
||||
</div>
|
||||
@@ -177,7 +177,7 @@
|
||||
</div>
|
||||
<p>* Champ obligatoire</p>
|
||||
<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>
|
||||
</div>
|
||||
</form>
|
||||
@@ -205,7 +205,7 @@
|
||||
<div class="flex flex-row">
|
||||
<button
|
||||
type="submit"
|
||||
class="bg-green-500 text-white mr-4 px-4 py-2 rounded hover:bg-green-600">
|
||||
class="btnSecondary">
|
||||
Importer CSV
|
||||
</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>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends 'main/base.html.twig' %}
|
||||
|
||||
{% block head %}
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
@@ -16,22 +17,24 @@
|
||||
<form action="{{ path('app_login') }}" method="post">
|
||||
<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>
|
||||
|
||||
<div class="mb-4">
|
||||
<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>
|
||||
<a id="openModal" class="text-blue-500 text-sm hover:underline">Mot de passe oublié ?</a>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" name="_remember_me" checked>
|
||||
Se souvenir de moi
|
||||
</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">
|
||||
<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') }}">
|
||||
<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>
|
||||
</div>
|
||||
</form>
|
||||
@@ -49,8 +52,8 @@
|
||||
</div>
|
||||
|
||||
<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="button" id="closeModal" class="ml-2 bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-700">Annuler</button>
|
||||
<button type="submit" class="btnPrimary">Envoyer</button>
|
||||
<button type="button" id="closeModal" class="btnAnnule ml-2">Annuler</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -68,6 +71,5 @@
|
||||
document.getElementById('resetModal').classList.add('hidden');
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{{ form_row(registrationForm.email) }}
|
||||
{{ form_row(registrationForm.pseudo) }}
|
||||
{{ 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) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
{{ 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">
|
||||
{% 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) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="flex flex-wrap justify-center">
|
||||
<div class="w-full px-4">
|
||||
<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
|
||||
</button>
|
||||
</a>
|
||||
|
||||
@@ -110,9 +110,6 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<button type="button" id="generate-image" class="modern-button mt-2">
|
||||
Générer une image
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -121,10 +118,7 @@
|
||||
<label for="sortie_lieu">Lieu</label>
|
||||
<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' } }) }}
|
||||
<button type="button" id="add-lieu-button" class="modern-button">
|
||||
<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>
|
||||
<button type="button" id="add-lieu-button" class="btnThird">
|
||||
Ajouter
|
||||
</button>
|
||||
</div>
|
||||
@@ -154,10 +148,10 @@
|
||||
</div>
|
||||
|
||||
<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
|
||||
</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
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -71,10 +71,10 @@
|
||||
</div>
|
||||
|
||||
<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
|
||||
</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
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
<!-- Bouton de filtrage -->
|
||||
<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
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
{% 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">
|
||||
<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
|
||||
</button>
|
||||
</form>
|
||||
@@ -88,7 +88,7 @@
|
||||
<p class="text-green-600 font-bold">✅ Vous êtes déjà inscrit à cette sortie.</p>
|
||||
{% if sortie.etat.libelle == 'Ouverte' %}
|
||||
<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
|
||||
</button>
|
||||
</form>
|
||||
@@ -102,9 +102,13 @@
|
||||
<button
|
||||
type="button"
|
||||
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
|
||||
</button>
|
||||
<a href="{{ path('sortie_edit', { id: sortie.idSortie }) }}"
|
||||
class="btnSecondary">
|
||||
✏️ Modifier la sortie
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if sortie.etat.libelle == 'Créée' %}
|
||||
<a href="{{ path('sortie_edit', { id: sortie.idSortie }) }}"
|
||||
@@ -170,7 +174,7 @@
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">
|
||||
class="btnAnnule">
|
||||
Confirmer l'annulation
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user