✅ Finalisation application : sécurité, calendrier, vérifs d’unicité, filtres chauffagiste
This commit is contained in:
parent
a992c2ea6a
commit
461e661f62
44
migrations/Version20250508121539.php
Normal file
44
migrations/Version20250508121539.php
Normal 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);
|
||||
}
|
||||
}
|
@ -13,24 +13,21 @@ class CalendrierController extends AbstractController
|
||||
#[Route('/chauffagiste', name: 'app_calendrier_indexChauffagiste')]
|
||||
public function indexChauffagiste(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
// Vérification : seul le chauffagiste connecté peut voir son propre calendrier
|
||||
$this->denyAccessUnlessGranted('ROLE_CHAUFFAGISTE');
|
||||
|
||||
// Récupérer les interventions du chauffagiste connecté
|
||||
$interventions = $interventionRepository->findByUser($this->getUser());
|
||||
|
||||
// Préparer les événements pour FullCalendar
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'title' => $intervention->getTitle(),
|
||||
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'),
|
||||
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'),
|
||||
'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
|
||||
'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'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', [
|
||||
'events' => json_encode($events),
|
||||
]);
|
||||
@ -39,24 +36,21 @@ class CalendrierController extends AbstractController
|
||||
#[Route('/secretaire', name: 'app_calendrier_indexSecretaire')]
|
||||
public function indexSecretaire(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
// Vérification : seul le secrétaire peut accéder à ce calendrier
|
||||
$this->denyAccessUnlessGranted('ROLE_SECRETAIRE');
|
||||
|
||||
// Récupérer toutes les interventions de tous les chauffagistes
|
||||
$interventions = $interventionRepository->findAll();
|
||||
|
||||
// Préparer les événements pour FullCalendar
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'title' => $intervention->getTitle(),
|
||||
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'),
|
||||
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'),
|
||||
'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
|
||||
'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'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', [
|
||||
'events' => json_encode($events),
|
||||
]);
|
||||
@ -65,24 +59,21 @@ class CalendrierController extends AbstractController
|
||||
#[Route('/admin', name: 'app_calendrier_index')]
|
||||
public function indexAdmin(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
// Vérification : seul un admin peut accéder à ce calendrier
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
// Récupérer toutes les interventions de tous les chauffagistes
|
||||
$interventions = $interventionRepository->findAll();
|
||||
|
||||
// Préparer les événements pour FullCalendar
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'title' => $intervention->getTitle(),
|
||||
'start' => $intervention->getStartDate()->format('Y-m-d H:i:s'),
|
||||
'end' => $intervention->getEndDate()->format('Y-m-d H:i:s'),
|
||||
'title' => ' - ' . $intervention->getWording() . ' (' . $intervention->getStatus() . ')',
|
||||
'start' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'end' => $intervention->getTimestamp()?->format('Y-m-d\TH:i:s') ?? '',
|
||||
'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', [
|
||||
'events' => json_encode($events),
|
||||
]);
|
||||
|
@ -4,6 +4,7 @@ namespace App\Controller;
|
||||
|
||||
use App\Entity\Intervention;
|
||||
use App\Form\InterventionType;
|
||||
use App\Form\RemarqueType;
|
||||
use App\Repository\InterventionRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
@ -24,7 +25,7 @@ class InterventionController extends AbstractController
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
||||
@ -33,6 +34,36 @@ class InterventionController extends AbstractController
|
||||
$form->handleRequest($request);
|
||||
|
||||
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->flush();
|
||||
|
||||
@ -54,7 +85,7 @@ class InterventionController extends AbstractController
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
||||
@ -62,8 +93,49 @@ class InterventionController extends AbstractController
|
||||
$form->handleRequest($request);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
@ -89,7 +161,6 @@ class InterventionController extends AbstractController
|
||||
#[Route('/{id}/remarque', name: 'app_intervention_remarque', methods: ['GET', 'POST'])]
|
||||
public function ajouterRemarque(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
// Vérifie que l'utilisateur est le chauffagiste assigné à l'intervention
|
||||
$user = $this->getUser();
|
||||
if (!$this->isGranted('ROLE_CHAUFFAGISTE') || $intervention->getUser() !== $user) {
|
||||
throw $this->createAccessDeniedException("Vous ne pouvez modifier que vos propres interventions.");
|
||||
@ -100,7 +171,6 @@ class InterventionController extends AbstractController
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'Remarque ajoutée avec succès.');
|
||||
return $this->redirectToRoute('app_intervention_show', ['id' => $intervention->getId()]);
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
#[IsGranted('ROLE_ADMIN')] // accès global restreint
|
||||
final class UserController extends AbstractController
|
||||
{
|
||||
// Route pour afficher tous les utilisateurs
|
||||
#[Route('/user', name: 'app_user_index', methods: ['GET'])]
|
||||
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'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher): Response
|
||||
{
|
||||
@ -33,7 +32,6 @@ final class UserController extends AbstractController
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
// Hash du mot de passe
|
||||
$plainPassword = $form->get('plainPassword')->getData();
|
||||
$hashedPassword = $passwordHasher->hashPassword($user, $plainPassword);
|
||||
$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'])]
|
||||
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'])]
|
||||
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->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'])]
|
||||
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'))) {
|
||||
$this->entityManager->remove($utilisateur);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$entityManager->remove($utilisateur);
|
||||
$entityManager->flush();
|
||||
$this->addFlash('success', 'Utilisateur supprimé avec succès.');
|
||||
} else {
|
||||
$this->addFlash('error', 'Token CSRF invalide.');
|
||||
|
@ -7,6 +7,7 @@ use App\Entity\Intervention;
|
||||
use App\Entity\Stock;
|
||||
use App\Entity\Utilisateur;
|
||||
use App\Entity\Vehicle;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
@ -28,7 +29,15 @@ class InterventionType extends AbstractType
|
||||
->add('Status', TextType::class)
|
||||
->add('user', EntityType::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, [
|
||||
'class' => Fault::class,
|
||||
@ -44,16 +53,7 @@ class InterventionType extends AbstractType
|
||||
'choice_label' => 'Wording',
|
||||
'multiple' => 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
|
||||
|
@ -95,18 +95,23 @@
|
||||
<ul>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<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_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_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>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('ROLE_SECRETAIRE') %}
|
||||
<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_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_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>
|
||||
{% endif %}
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
{% block body %}
|
||||
<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>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
|
||||
@ -14,29 +12,17 @@
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'dayGridMonth',
|
||||
events: '/api/interventions' // ✅ Point d’accès API
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
|
||||
calendar.render();
|
||||
});
|
||||
</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 %}
|
||||
|
@ -7,15 +7,20 @@
|
||||
|
||||
<div id="calendar"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
|
||||
|
||||
<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);
|
||||
}
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
|
@ -7,15 +7,20 @@
|
||||
|
||||
<div id="calendar"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
|
||||
|
||||
<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);
|
||||
}
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
|
@ -1,9 +1,3 @@
|
||||
{#{{ form_start(form) }}#}
|
||||
{# {{ form_widget(form) }}#}
|
||||
{# <button class="btn">{{ button_label|default('Save') }}</button>#}
|
||||
{#{{ form_end(form) }}#}
|
||||
|
||||
|
||||
{{ form_start(form) }}
|
||||
|
||||
<div class="form-group">
|
||||
@ -36,12 +30,30 @@
|
||||
{{ form_errors(form.Status) }}
|
||||
</div>
|
||||
|
||||
{#<div class="form-group">#}
|
||||
{# {{ form_label(form.vehicule, 'Véhicule associé') }}#}
|
||||
{# {{ form_widget(form.vehicule, {'attr': {'class': 'form-control'}}) }}#}
|
||||
{# {{ form_errors(form.vehicule) }}#}
|
||||
{#</div>#}
|
||||
<div class="form-group">
|
||||
{{ form_label(form.fault, 'Panne') }}
|
||||
{{ form_widget(form.fault, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.fault) }}
|
||||
</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) }}
|
||||
|
@ -5,67 +5,7 @@
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Créer une nouvelle intervention</h1>
|
||||
|
||||
{#<<<<<<< HEAD#}
|
||||
<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') }}
|
||||
</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 %}
|
||||
{#>>>>>>> 4fc91211f0d814453d2ed97caf6a1d94d709058e#}
|
||||
|
Loading…
x
Reference in New Issue
Block a user