Finalisation application : sécurité, calendrier, vérifs d’unicité, filtres chauffagiste

This commit is contained in:
sermandm 2025-05-08 15:07:12 +02:00
parent a992c2ea6a
commit 461e661f62
11 changed files with 205 additions and 165 deletions

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250508121539 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
ALTER TABLE intervention ADD remarque TEXT DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE intervention ADD start_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL
SQL);
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
CREATE SCHEMA public
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE intervention DROP remarque
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE intervention DROP start_date
SQL);
}
}

View File

@ -13,24 +13,21 @@ class CalendrierController extends AbstractController
#[Route('/chauffagiste', name: 'app_calendrier_indexChauffagiste')] #[Route('/chauffagiste', name: 'app_calendrier_indexChauffagiste')]
public function indexChauffagiste(InterventionRepository $interventionRepository): Response public function indexChauffagiste(InterventionRepository $interventionRepository): Response
{ {
// Vérification : seul le chauffagiste connecté peut voir son propre calendrier
$this->denyAccessUnlessGranted('ROLE_CHAUFFAGISTE'); $this->denyAccessUnlessGranted('ROLE_CHAUFFAGISTE');
// Récupérer les interventions du chauffagiste connecté
$interventions = $interventionRepository->findByUser($this->getUser()); $interventions = $interventionRepository->findByUser($this->getUser());
// Préparer les événements pour FullCalendar
$events = []; $events = [];
foreach ($interventions as $intervention) { foreach ($interventions as $intervention) {
$events[] = [ $events[] = [
'title' => $intervention->getTitle(), 'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'), 'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'), 'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'description' => $intervention->getDescription(), 'description' => $intervention->getDescription(),
'url' => $this->generateUrl('app_intervention_show', ['id' => $intervention->getId()])
]; ];
} }
// Passer les événements à la vue
return $this->render('calendrier/indexChauffagiste.html.twig', [ return $this->render('calendrier/indexChauffagiste.html.twig', [
'events' => json_encode($events), 'events' => json_encode($events),
]); ]);
@ -39,24 +36,21 @@ class CalendrierController extends AbstractController
#[Route('/secretaire', name: 'app_calendrier_indexSecretaire')] #[Route('/secretaire', name: 'app_calendrier_indexSecretaire')]
public function indexSecretaire(InterventionRepository $interventionRepository): Response public function indexSecretaire(InterventionRepository $interventionRepository): Response
{ {
// Vérification : seul le secrétaire peut accéder à ce calendrier
$this->denyAccessUnlessGranted('ROLE_SECRETAIRE'); $this->denyAccessUnlessGranted('ROLE_SECRETAIRE');
// Récupérer toutes les interventions de tous les chauffagistes
$interventions = $interventionRepository->findAll(); $interventions = $interventionRepository->findAll();
// Préparer les événements pour FullCalendar
$events = []; $events = [];
foreach ($interventions as $intervention) { foreach ($interventions as $intervention) {
$events[] = [ $events[] = [
'title' => $intervention->getTitle(), 'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'), 'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'), 'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'description' => $intervention->getDescription(), 'description' => $intervention->getDescription(),
'url' => $this->generateUrl('app_intervention_show', ['id' => $intervention->getId()])
]; ];
} }
// Passer les événements à la vue
return $this->render('calendrier/indexSecretaire.html.twig', [ return $this->render('calendrier/indexSecretaire.html.twig', [
'events' => json_encode($events), 'events' => json_encode($events),
]); ]);
@ -65,24 +59,21 @@ class CalendrierController extends AbstractController
#[Route('/admin', name: 'app_calendrier_index')] #[Route('/admin', name: 'app_calendrier_index')]
public function indexAdmin(InterventionRepository $interventionRepository): Response public function indexAdmin(InterventionRepository $interventionRepository): Response
{ {
// Vérification : seul un admin peut accéder à ce calendrier
$this->denyAccessUnlessGranted('ROLE_ADMIN'); $this->denyAccessUnlessGranted('ROLE_ADMIN');
// Récupérer toutes les interventions de tous les chauffagistes
$interventions = $interventionRepository->findAll(); $interventions = $interventionRepository->findAll();
// Préparer les événements pour FullCalendar
$events = []; $events = [];
foreach ($interventions as $intervention) { foreach ($interventions as $intervention) {
$events[] = [ $events[] = [
'title' => $intervention->getTitle(), 'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'), 'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'), 'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
'description' => $intervention->getDescription(), 'description' => $intervention->getDescription(),
'url' => $this->generateUrl('app_intervention_show', ['id' => $intervention->getId()])
]; ];
} }
// Passer les événements à la vue
return $this->render('calendrier/index.html.twig', [ return $this->render('calendrier/index.html.twig', [
'events' => json_encode($events), 'events' => json_encode($events),
]); ]);

View File

@ -4,6 +4,7 @@ namespace App\Controller;
use App\Entity\Intervention; use App\Entity\Intervention;
use App\Form\InterventionType; use App\Form\InterventionType;
use App\Form\RemarqueType;
use App\Repository\InterventionRepository; use App\Repository\InterventionRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -24,7 +25,7 @@ class InterventionController extends AbstractController
} }
#[Route('/new', name: 'app_intervention_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_intervention_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response public function new(Request $request, EntityManagerInterface $entityManager, InterventionRepository $interventionRepository): Response
{ {
$this->denyUnlessAdminOrSecretaire(); $this->denyUnlessAdminOrSecretaire();
@ -33,6 +34,36 @@ class InterventionController extends AbstractController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$timestamp = $intervention->getTimestamp();
$chauffagiste = $intervention->getUser();
$vehicule = $intervention->getVehicle();
$conflictsUser = $interventionRepository->findBy([
'Timestamp' => $timestamp,
'user' => $chauffagiste,
]);
if ($conflictsUser) {
$this->addFlash('error', 'Ce chauffagiste a déjà une intervention à cette date.');
return $this->render('intervention/new.html.twig', [
'form' => $form,
]);
}
if ($vehicule) {
$conflictsVehicule = $interventionRepository->findBy([
'Timestamp' => $timestamp,
'vehicle' => $vehicule,
]);
if ($conflictsVehicule) {
$this->addFlash('error', 'Ce véhicule est déjà utilisé à cette date.');
return $this->render('intervention/new.html.twig', [
'form' => $form,
]);
}
}
$entityManager->persist($intervention); $entityManager->persist($intervention);
$entityManager->flush(); $entityManager->flush();
@ -54,7 +85,7 @@ class InterventionController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_intervention_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_intervention_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response public function edit(Request $request, Intervention $intervention, EntityManagerInterface $entityManager, InterventionRepository $interventionRepository): Response
{ {
$this->denyUnlessAdminOrSecretaire(); $this->denyUnlessAdminOrSecretaire();
@ -62,8 +93,49 @@ class InterventionController extends AbstractController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush(); $timestamp = $intervention->getTimestamp();
$chauffagiste = $intervention->getUser();
$vehicule = $intervention->getVehicle();
$conflictUser = $interventionRepository->createQueryBuilder('i')
->where('i.Timestamp = :time')
->andWhere('i.user = :user')
->andWhere('i != :current')
->setParameter('time', $timestamp)
->setParameter('user', $chauffagiste)
->setParameter('current', $intervention)
->getQuery()
->getResult();
if ($conflictUser) {
$this->addFlash('error', 'Ce chauffagiste a déjà une autre intervention à cette date.');
return $this->render('intervention/edit.html.twig', [
'form' => $form,
'intervention' => $intervention,
]);
}
if ($vehicule) {
$conflictVehicule = $interventionRepository->createQueryBuilder('i')
->where('i.Timestamp = :time')
->andWhere('i.vehicle = :vehicule')
->andWhere('i != :current')
->setParameter('time', $timestamp)
->setParameter('user', $chauffagiste)
->setParameter('current', $intervention)
->getQuery()
->getResult();
if ($conflictVehicule) {
$this->addFlash('error', 'Ce véhicule est déjà utilisé à cette date.');
return $this->render('intervention/edit.html.twig', [
'form' => $form,
'intervention' => $intervention,
]);
}
}
$entityManager->flush();
return $this->redirectToRoute('app_intervention_index'); return $this->redirectToRoute('app_intervention_index');
} }
@ -89,7 +161,6 @@ class InterventionController extends AbstractController
#[Route('/{id}/remarque', name: 'app_intervention_remarque', methods: ['GET', 'POST'])] #[Route('/{id}/remarque', name: 'app_intervention_remarque', methods: ['GET', 'POST'])]
public function ajouterRemarque(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response public function ajouterRemarque(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response
{ {
// Vérifie que l'utilisateur est le chauffagiste assigné à l'intervention
$user = $this->getUser(); $user = $this->getUser();
if (!$this->isGranted('ROLE_CHAUFFAGISTE') || $intervention->getUser() !== $user) { if (!$this->isGranted('ROLE_CHAUFFAGISTE') || $intervention->getUser() !== $user) {
throw $this->createAccessDeniedException("Vous ne pouvez modifier que vos propres interventions."); throw $this->createAccessDeniedException("Vous ne pouvez modifier que vos propres interventions.");
@ -100,7 +171,6 @@ class InterventionController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'Remarque ajoutée avec succès.'); $this->addFlash('success', 'Remarque ajoutée avec succès.');
return $this->redirectToRoute('app_intervention_show', ['id' => $intervention->getId()]); return $this->redirectToRoute('app_intervention_show', ['id' => $intervention->getId()]);
} }

View File

@ -13,9 +13,9 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')] // accès global restreint
final class UserController extends AbstractController final class UserController extends AbstractController
{ {
// Route pour afficher tous les utilisateurs
#[Route('/user', name: 'app_user_index', methods: ['GET'])] #[Route('/user', name: 'app_user_index', methods: ['GET'])]
public function index(UserRepository $userRepository): Response public function index(UserRepository $userRepository): Response
{ {
@ -24,7 +24,6 @@ final class UserController extends AbstractController
]); ]);
} }
// Route pour créer un nouvel utilisateur
#[Route('/user/new', name: 'app_user_new', methods: ['GET', 'POST'])] #[Route('/user/new', name: 'app_user_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher): Response public function new(Request $request, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher): Response
{ {
@ -33,7 +32,6 @@ final class UserController extends AbstractController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
// Hash du mot de passe
$plainPassword = $form->get('plainPassword')->getData(); $plainPassword = $form->get('plainPassword')->getData();
$hashedPassword = $passwordHasher->hashPassword($user, $plainPassword); $hashedPassword = $passwordHasher->hashPassword($user, $plainPassword);
$user->setPassword($hashedPassword); $user->setPassword($hashedPassword);
@ -50,7 +48,6 @@ final class UserController extends AbstractController
]); ]);
} }
// Route pour afficher un utilisateur spécifique
#[Route('/user/{id}', name: 'app_user_show', methods: ['GET'])] #[Route('/user/{id}', name: 'app_user_show', methods: ['GET'])]
public function show(Utilisateur $user): Response public function show(Utilisateur $user): Response
{ {
@ -59,21 +56,9 @@ final class UserController extends AbstractController
]); ]);
} }
// Route pour modifier un utilisateur spécifique
#[Route('/user/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])] #[Route('/user/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Utilisateur $user, EntityManagerInterface $entityManager): Response public function edit(Request $request, Utilisateur $user, EntityManagerInterface $entityManager): Response
{ {
if ($this->isGranted('ROLE_SECRETAIRE') && $user->hasRole('ROLE_SECRETAIRE')) {
throw $this->createAccessDeniedException('Vous ne pouvez pas modifier un autre secrétaire.');
}
if ($this->isGranted('ROLE_CHAUFFAGISTE') && ($user->hasRole('ROLE_CHAUFFAGISTE') || $user->hasRole('ROLE_SECRETAIRE'))) {
throw $this->createAccessDeniedException('Vous ne pouvez pas modifier un admin.');
}
// On s'assure que seul un admin peut éditer un autre admin
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$form = $this->createForm(UserType::class, $user); $form = $this->createForm(UserType::class, $user);
$form->handleRequest($request); $form->handleRequest($request);
@ -89,15 +74,12 @@ final class UserController extends AbstractController
]); ]);
} }
// Route pour supprimer un utilisateur spécifique
#[IsGranted('ROLE_ADMIN', 'ROLE_SECRETAIRE')]
#[Route('/user/{id}', name: 'app_user_delete', methods: ['POST'])] #[Route('/user/{id}', name: 'app_user_delete', methods: ['POST'])]
public function delete(Request $request, Utilisateur $utilisateur): Response public function delete(Request $request, Utilisateur $utilisateur, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete' . $utilisateur->getId(), $request->request->get('_token'))) { if ($this->isCsrfTokenValid('delete' . $utilisateur->getId(), $request->request->get('_token'))) {
$this->entityManager->remove($utilisateur); $entityManager->remove($utilisateur);
$this->entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'Utilisateur supprimé avec succès.'); $this->addFlash('success', 'Utilisateur supprimé avec succès.');
} else { } else {
$this->addFlash('error', 'Token CSRF invalide.'); $this->addFlash('error', 'Token CSRF invalide.');

View File

@ -7,6 +7,7 @@ use App\Entity\Intervention;
use App\Entity\Stock; use App\Entity\Stock;
use App\Entity\Utilisateur; use App\Entity\Utilisateur;
use App\Entity\Vehicle; use App\Entity\Vehicle;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
@ -28,7 +29,15 @@ class InterventionType extends AbstractType
->add('Status', TextType::class) ->add('Status', TextType::class)
->add('user', EntityType::class, [ ->add('user', EntityType::class, [
'class' => Utilisateur::class, 'class' => Utilisateur::class,
'choice_label' => 'FirstName', // ou autre (LastName, email) 'choice_label' => function (Utilisateur $user) {
return $user->getFirstName() . ' ' . $user->getLastName();
},
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('JSON_CONTAINS(u.roles, :role) = 1')
->setParameter('role', '"ROLE_CHAUFFAGISTE"');
},
'label' => 'Chauffagiste assigné',
]) ])
->add('fault', EntityType::class, [ ->add('fault', EntityType::class, [
'class' => Fault::class, 'class' => Fault::class,
@ -44,16 +53,7 @@ class InterventionType extends AbstractType
'choice_label' => 'Wording', 'choice_label' => 'Wording',
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
]) ]);
;
// // 👉 Sélecteur de véhicule
// ->add('vehicule', EntityType::class, [
// 'class' => Vehicule::class,
// 'choice_label' => 'immatriculation', // ou n'importe quel champ que tu veux afficher
// 'placeholder' => 'Aucun véhicule sélectionné',
// 'required' => false,
// ]);
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void

View File

@ -95,18 +95,23 @@
<ul> <ul>
{% if is_granted('ROLE_ADMIN') %} {% if is_granted('ROLE_ADMIN') %}
<li><a href="{{ path('admin_dashboard') }}">Dashboard Admin</a></li> <li><a href="{{ path('admin_dashboard') }}">Dashboard Admin</a></li>
<li><a href="{{ path('app_intervention_index') }}">Gérer les interventions</a></li>
<li><a href="{{ path('app_user_index') }}">Gérer les utilisateurs</a></li> <li><a href="{{ path('app_user_index') }}">Gérer les utilisateurs</a></li>
<li><a href="{{ path('app_vehicle_index') }}">Gérer les véhicules</a></li> <li><a href="{{ path('app_vehicle_index') }}">Gérer les véhicules</a></li>
<li><a href="{{ path('app_stock_index') }}">Gérer les stocks</a></li> <li><a href="{{ path('app_stock_index') }}">Gérer les stocks</a></li>
<li><a href="{{ path('app_fault_index') }}">Gérer les pannes</a></li> <li><a href="{{ path('app_fault_index') }}">Gérer les pannes</a></li>
<li><a href="{{ path('app_skill_index') }}">Gérer les compétences</a></li>
<li><a href="{{ path('app_calendrier_index') }}">Tous les plannings</a></li> <li><a href="{{ path('app_calendrier_index') }}">Tous les plannings</a></li>
{% endif %} {% endif %}
{% if is_granted('ROLE_SECRETAIRE') %} {% if is_granted('ROLE_SECRETAIRE') %}
<li><a href="{{ path('secretaire_dashboard') }}">Dashboard Secrétaire</a></li> <li><a href="{{ path('secretaire_dashboard') }}">Dashboard Secrétaire</a></li>
<li><a href="{{ path('app_intervention_index') }}">Gérer les interventions</a></li>
<li><a href="{{ path('app_user_index') }}">Créer un chauffagiste</a></li> <li><a href="{{ path('app_user_index') }}">Créer un chauffagiste</a></li>
<li><a href="{{ path('app_vehicle_index') }}">Gérer les véhicules</a></li> <li><a href="{{ path('app_vehicle_index') }}">Gérer les véhicules</a></li>
<li><a href="{{ path('app_stock_index') }}">Gérer les stocks</a></li> <li><a href="{{ path('app_stock_index') }}">Gérer les stocks</a></li>
<li><a href="{{ path('app_fault_index') }}">Gérer les pannes</a></li>
<li><a href="{{ path('app_skill_index') }}">Gérer les compétences</a></li>
<li><a href="{{ path('app_calendrier_indexSecretaire') }}">Plannings chauffagistes</a></li> <li><a href="{{ path('app_calendrier_indexSecretaire') }}">Plannings chauffagistes</a></li>
{% endif %} {% endif %}

View File

@ -5,38 +5,24 @@
{% block body %} {% block body %}
<h1>📅 Calendrier des interventions</h1> <h1>📅 Calendrier des interventions</h1>
<a href="{{ path('app_intervention_new') }}" class="btn btn-success mt-3"> Ajouter une intervention</a>
<div id="calendar"></div> <div id="calendar"></div>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar'); var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, { var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth', initialView: 'dayGridMonth',
events: '/api/interventions' // ✅ Point daccès API locale: 'fr',
eventTimeFormat: {
hour: '2-digit',
minute: '2-digit',
hour12: false
},
events: {{ events|raw }}
}); });
calendar.render(); calendar.render();
}); });
</script> </script>
{# <div id="calendar"></div>#}
{# <script>#}
{# document.addEventListener('DOMContentLoaded', function() {#}
{# var calendarEl = document.getElementById('calendar');#}
{# var calendar = new FullCalendar.Calendar(calendarEl, {#}
{# initialView: 'dayGridMonth',#}
{# events: {{ events | raw }},#}
{# eventClick: function(info) {#}
{# alert('Intervention : ' + info.event.title + '\n' + info.event.extendedProps.description);#}
{# }#}
{# });#}
{# calendar.render();#}
{# });#}
{# </script>#}
{% endblock %} {% endblock %}

View File

@ -7,15 +7,20 @@
<div id="calendar"></div> <div id="calendar"></div>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar'); var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, { var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth', initialView: 'dayGridMonth',
events: {{ events | raw }}, locale: 'fr',
eventClick: function(info) { eventTimeFormat: {
alert('Intervention : ' + info.event.title + '\n' + info.event.extendedProps.description); hour: '2-digit',
} minute: '2-digit',
hour12: false
},
events: {{ events|raw }}
}); });
calendar.render(); calendar.render();
}); });

View File

@ -7,15 +7,20 @@
<div id="calendar"></div> <div id="calendar"></div>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar'); var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, { var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth', initialView: 'dayGridMonth',
events: {{ events | raw }}, locale: 'fr',
eventClick: function(info) { eventTimeFormat: {
alert('Intervention : ' + info.event.title + '\n' + info.event.extendedProps.description); hour: '2-digit',
} minute: '2-digit',
hour12: false
},
events: {{ events|raw }}
}); });
calendar.render(); calendar.render();
}); });

View File

@ -1,9 +1,3 @@
{#{{ form_start(form) }}#}
{# {{ form_widget(form) }}#}
{# <button class="btn">{{ button_label|default('Save') }}</button>#}
{#{{ form_end(form) }}#}
{{ form_start(form) }} {{ form_start(form) }}
<div class="form-group"> <div class="form-group">
@ -36,12 +30,30 @@
{{ form_errors(form.Status) }} {{ form_errors(form.Status) }}
</div> </div>
{#<div class="form-group">#} <div class="form-group">
{# {{ form_label(form.vehicule, 'Véhicule associé') }}#} {{ form_label(form.fault, 'Panne') }}
{# {{ form_widget(form.vehicule, {'attr': {'class': 'form-control'}}) }}#} {{ form_widget(form.fault, {'attr': {'class': 'form-control'}}) }}
{# {{ form_errors(form.vehicule) }}#} {{ form_errors(form.fault) }}
{#</div>#} </div>
<button class="btn btn-primary mt-3">{{ button_label|default('Enregistrer') }}</button> <div class="form-group">
{{ form_label(form.user, 'Chauffagiste assigné') }}
{{ form_widget(form.user, {'attr': {'class': 'form-control'}}) }}
{{ form_errors(form.user) }}
</div>
<div class="form-group">
{{ form_label(form.vehicle, 'Véhicule') }}
{{ form_widget(form.vehicle, {'attr': {'class': 'form-control'}}) }}
{{ form_errors(form.vehicle) }}
</div>
<div class="form-group">
{{ form_label(form.stocks, 'Pièces utilisées') }}
{{ form_widget(form.stocks, {'attr': {'class': 'form-control'}}) }}
{{ form_errors(form.stocks) }}
</div>
<button class="btn btn-primary mt-4">{{ button_label|default('Enregistrer') }}</button>
{{ form_end(form) }} {{ form_end(form) }}

View File

@ -5,67 +5,7 @@
{% block body %} {% block body %}
<h1 class="mb-4"> Créer une nouvelle intervention</h1> <h1 class="mb-4"> Créer une nouvelle intervention</h1>
{#<<<<<<< HEAD#}
<div class="background-intervention"> <div class="background-intervention">
{# <input required id="nom" placeholder="Nom de l'intervention">#}
{# <select required type="select" name="pannes" id="pannes">#}
{# <option value="pan1">pan1</option>#}
{# <option value="pan2">pan2</option>#}
{# <option value="pan3">pan3</option>#}
{# <option value="pan4">pan4</option>#}
{# <option value="pan5">pan5</option>#}
{# <option value="pan6">pan6</option>#}
{# </select>#}
{# <select required type="select" name="pannes" id="employesCompetences">#}
{# <option value="emp1">employé1 - sa compétence</option>#}
{# <option value="emp2">employé2 - sa compétence</option>#}
{# <option value="emp3">employé3 - sa compétence</option>#}
{# <option value="emp4">employé4 - sa compétence</option>#}
{# <option value="emp5">employé5 - sa compétence</option>#}
{# <option value="emp6">employé6 - sa compétence</option>#}
{# </select>#}
{# <!-- <input required id="employesCompetences" placeholder="Liste des employés et de leurs compétences"> -->#}
{# <select required type="select" name="piece" id="piece">#}
{# <option value="pièce1">Pièce affecter 1</option>#}
{# <option value="pièce2">Pièce affecter 2</option>#}
{# <option value="pièce3">Pièce affecter 3</option>#}
{# <option value="pièce4">Pièce affecter 4</option>#}
{# <option value="pièce5">Pièce affecter 5</option>#}
{# <option value="pièce6">Pièce affecter 6</option>#}
{# </select>#}
{# <p id="vehicule">Véhicule nécessaire</p>#}
{# <form>#}
{# <label id="oui">#}
{# <input type="radio" name="choix" value="option1">#}
{# Oui </label>#}
{# <label id="non">#}
{# <input type="radio" name="choix" value="option2">#}
{# Non </label>#}
{# </form>#}
{# <p id="date">Jour de l'intervention</p>#}
{# <input type="date" id="calendar">#}
{# <input type="text" id="description" placeholder="Description">#}
{# <input type="text" id="adresse" placeholder="Adresse">#}
{# <button type="submit" class="applique"> Appliquée </button>#}
{# <button type="reset" class="supprimer"> Supprimer </button>#}
{{ include('intervention/_form.html.twig') }} {{ include('intervention/_form.html.twig') }}
</div> </div>
</body>
</html>
{#=======#}
<div class="mt-3">
<a href="{{ path('app_intervention_index') }}" class="btn btn-secondary">← Retour à la liste des interventions</a>
</div>
<div class="mt-3">
<a href="{{ path('app_calendrier_index') }}" class="btn btn-secondary">← Retour au calendrier</a>
</div>
{% endblock %} {% endblock %}
{#>>>>>>> 4fc91211f0d814453d2ed97caf6a1d94d709058e#}