Compare commits
No commits in common. "master" and "feature/Giovanny" have entirely different histories.
master
...
feature/Gi
2
.idea/HegreEtConfort.iml
generated
2
.idea/HegreEtConfort.iml
generated
@ -135,10 +135,8 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/extra-bundle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/twig" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php84" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="fullcalendar" level="application" />
|
||||
</component>
|
||||
</module>
|
4
.idea/dataSources.xml
generated
4
.idea/dataSources.xml
generated
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="@localhost" uuid="21423ae4-3232-4641-affb-06399f70655a">
|
||||
<data-source source="LOCAL" name="HegreEtConfort@172.20.96.1" uuid="21423ae4-3232-4641-affb-06399f70655a">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://localhost:5433/</jdbc-url>
|
||||
<jdbc-url>jdbc:postgresql://172.20.96.1:5432/HegreEtConfort</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
|
16
.idea/php.xml
generated
16
.idea/php.xml
generated
@ -10,11 +10,6 @@
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpCodeSniffer">
|
||||
<phpcs_settings>
|
||||
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="4bd9484f-d78e-4315-b899-c673e4a83c70" timeout="30000" />
|
||||
</phpcs_settings>
|
||||
</component>
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||
@ -147,15 +142,9 @@
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
<component name="PhpStan">
|
||||
<PhpStan_settings>
|
||||
<phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="4bd9484f-d78e-4315-b899-c673e4a83c70" timeout="60000" />
|
||||
</PhpStan_settings>
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
@ -164,11 +153,6 @@
|
||||
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml.dist" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
||||
</phpunit_settings>
|
||||
</component>
|
||||
<component name="Psalm">
|
||||
<Psalm_settings>
|
||||
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="4bd9484f-d78e-4315-b899-c673e4a83c70" timeout="60000" />
|
||||
</Psalm_settings>
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
|
99
README.md
99
README.md
@ -1,99 +0,0 @@
|
||||
# 🚀 Application de Gestion Chauffagiste
|
||||
|
||||
## Description
|
||||
Cette application permet de gérer les interventions, les utilisateurs (chauffagistes, secrétaires, admins), les pièces détachées, les véhicules, et les plannings dans une entreprise de chauffagistes.
|
||||
|
||||
---
|
||||
|
||||
## Fonctionnalités principales
|
||||
- **Gestion des utilisateurs** : création de chauffagistes, secrétaires, et admins avec des rôles spécifiques.
|
||||
- **Gestion des interventions** : assignation des chauffagistes, véhicules, pièces détachées, ajout de remarques.
|
||||
- **Gestion des stocks et des véhicules** : CRUD complet pour les pièces détachées et les véhicules.
|
||||
- **Planning des interventions** : chaque rôle accède à un planning personnalisé (chauffagiste, secrétaire, admin).
|
||||
- **Sécurisation par rôles** : accès aux pages limité par rôle (Admin, Secrétaire, Chauffagiste).
|
||||
|
||||
---
|
||||
|
||||
## Fonctionnalités avancées
|
||||
- ✅ **Contrôle d’unicité** : interdiction de double-assignation d’un même chauffagiste ou véhicule sur une même date/heure.
|
||||
- ✅ **Calendrier FullCalendar dynamique** : affichage différent selon le rôle + clic pour afficher l’intervention.
|
||||
- ✅ **Sélecteurs intelligents** : seuls les chauffagistes apparaissent pour l’assignation dans les interventions.
|
||||
- ✅ **Remarque chauffagiste** : chaque chauffagiste peut ajouter une remarque à ses interventions uniquement.
|
||||
- ✅ **Sécurité renforcée** : vérifications d’accès sur toutes les routes sensibles.
|
||||
|
||||
---
|
||||
|
||||
## Rôles & restrictions
|
||||
|
||||
| Rôle | Droits |
|
||||
|---------------|------------------------------------------------------------------------|
|
||||
| **Admin** | Accès complet à tous les modules (utilisateurs, stocks, véhicules...) |
|
||||
| **Secrétaire** | Accès complet à tous les modules **mais pas aux utilisateurs** |
|
||||
| **Chauffagiste** | Accède uniquement à ses interventions et peut y ajouter des remarques |
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Prérequis :
|
||||
- PHP 8.x
|
||||
- Composer
|
||||
- Symfony 7.x
|
||||
- Base de données PostgreSQL ou MySQL
|
||||
|
||||
### Étapes :
|
||||
### 1. Clonez le projet
|
||||
```bash
|
||||
git clone https://gitea.btssio-poitiers.fr/sermandm/HegreEtConfort.git
|
||||
cd HegreEtConfort
|
||||
```
|
||||
### 2. Installez les dépendances
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
### 3. Créez la base de données
|
||||
```bash
|
||||
php bin/console doctrine:database:create
|
||||
```
|
||||
### 4. Appliquez les migrations
|
||||
```bash
|
||||
php bin/console doctrine:migrations:migrate
|
||||
```
|
||||
|
||||
### 5. Créez un utilisateur admin (exemple PostgreSQL) :
|
||||
```sql
|
||||
INSERT INTO "HegreEtConfort".public.utilisateur (
|
||||
id, email, first_name, last_name, birth_date, phone, roles, password
|
||||
)
|
||||
VALUES (
|
||||
1000, 'admin@admin.admin', 'admin', 'admin', '2025-04-10', '0000000000',
|
||||
'["ROLE_ADMIN"]',
|
||||
'$2y$13$4jqoZVgncgDJ6oPFDswZeeiVmt9TF2AC.xoBwyyrrbNl5Xz8r.50e'
|
||||
);
|
||||
```
|
||||
|
||||
### 6. Démarrez le serveur Symfony :
|
||||
```bash
|
||||
symfony server:start
|
||||
```
|
||||
|
||||
➡️ Accédez ensuite à l’application : [http://localhost:8000](http://localhost:8000)
|
||||
|
||||
---
|
||||
|
||||
## Technologies utilisées
|
||||
- Symfony 7.x
|
||||
- Doctrine ORM
|
||||
- Twig
|
||||
- PHP 8.x
|
||||
- FullCalendar.js
|
||||
- PostgreSQL (ou MySQL selon config)
|
||||
|
||||
---
|
||||
|
||||
## Auteur
|
||||
Développé dans le cadre du BTS SIO - D'Hegre Et Confort
|
||||
- Maxim SERMAND
|
||||
- Alyssa ALLARD
|
||||
- Giovanny BRUNET
|
||||
- Lucas RAGUENEAU
|
@ -1,7 +1,3 @@
|
||||
body {
|
||||
background: url("../image/fond.png") center center / cover no-repeat !important;
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
@ -108,19 +108,19 @@ body {
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
}
|
||||
#oui {
|
||||
#vehicule1 {
|
||||
position: absolute;
|
||||
margin: 30.7% 0 0 25%;
|
||||
}
|
||||
#oui p {
|
||||
#oui {
|
||||
position: absolute;
|
||||
margin: 30.3% 0 0 27%;
|
||||
}
|
||||
#non {
|
||||
#vehicule2 {
|
||||
position: absolute;
|
||||
margin: 30.7% 0 0 32%;
|
||||
}
|
||||
#non p {
|
||||
#non {
|
||||
position: absolute;
|
||||
margin: 30.3% 0 0 34%;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
4
assets/vendor/@hotwired/turbo/turbo.index.js
vendored
4
assets/vendor/@hotwired/turbo/turbo.index.js
vendored
@ -1,9 +1,5 @@
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* Bundled by jsDelivr using Rollup v2.79.1 and Terser v5.19.2.
|
||||
=======
|
||||
* Bundled by jsDelivr using Rollup v2.79.2 and Terser v5.39.0.
|
||||
>>>>>>> b29391d6550c182d7b75efab8795a238c1936a27
|
||||
* Original file: /npm/@hotwired/turbo@7.3.0/dist/turbo.es2017-esm.js
|
||||
*
|
||||
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
|
||||
|
1341
composer.lock
generated
1341
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,50 +1,55 @@
|
||||
security:
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
# used to reload user from session & other features (e.g. switch_user)
|
||||
app_user_provider:
|
||||
entity:
|
||||
class: App\Entity\Utilisateur
|
||||
property: email
|
||||
firewalls:
|
||||
main:
|
||||
lazy: true
|
||||
provider: app_user_provider
|
||||
form_login:
|
||||
login_path: app_login
|
||||
check_path: app_login
|
||||
success_handler: App\Security\CustomAuthenticationSuccessHandler
|
||||
enable_csrf: true
|
||||
csrf_token_id: authenticate
|
||||
logout:
|
||||
path: app_logout
|
||||
target: app_login
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
# used to reload user from session & other features (e.g. switch_user)
|
||||
app_user_provider:
|
||||
entity:
|
||||
class: App\Entity\Utilisateur
|
||||
property: email
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
main:
|
||||
lazy: true
|
||||
provider: app_user_provider
|
||||
|
||||
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||
# switch_user: true
|
||||
form_login:
|
||||
login_path: app_login
|
||||
check_path: app_login
|
||||
enable_csrf: true
|
||||
csrf_token_id: authenticate
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||
- { path: ^/secretaire, roles: ROLE_SECRETAIRE }
|
||||
- { path: ^/chauffagiste, roles: ROLE_CHAUFFAGISTE }
|
||||
logout:
|
||||
path: app_logout
|
||||
target: app_login
|
||||
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
|
||||
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||
# switch_user: true
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||
- { path: ^/profile, roles: ROLE_USER }
|
||||
|
||||
when@test:
|
||||
security:
|
||||
password_hashers:
|
||||
# By default, password hashers are resource intensive and take time. This is
|
||||
# important to generate secure password hashes. In tests however, secure hashes
|
||||
# are not important, waste resources and increase test times. The following
|
||||
# reduces the work factor to the lowest possible values.
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||
algorithm: auto
|
||||
cost: 4 # Lowest possible value for bcrypt
|
||||
time_cost: 3 # Lowest possible value for argon
|
||||
memory_cost: 10 # Lowest possible value for argon
|
||||
security:
|
||||
password_hashers:
|
||||
# By default, password hashers are resource intensive and take time. This is
|
||||
# important to generate secure password hashes. In tests however, secure hashes
|
||||
# are not important, waste resources and increase test times. The following
|
||||
# reduces the work factor to the lowest possible values.
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||
algorithm: auto
|
||||
cost: 4 # Lowest possible value for bcrypt
|
||||
time_cost: 3 # Lowest possible value for argon
|
||||
memory_cost: 10 # Lowest possible value for argon
|
||||
|
71
migrations/Version20250410150126.php
Normal file
71
migrations/Version20250410150126.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?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 Version20250410150126 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('CREATE SEQUENCE fault_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE SEQUENCE intervention_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE SEQUENCE skill_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE SEQUENCE stock_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE SEQUENCE utilisateur_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE SEQUENCE vehicle_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE fault (id INT NOT NULL, wording VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE TABLE intervention (id INT NOT NULL, wording VARCHAR(255) NOT NULL, timestamp TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, description VARCHAR(255) NOT NULL, address VARCHAR(255) NOT NULL, status VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE TABLE skill (id INT NOT NULL, wording VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE TABLE stock (id INT NOT NULL, wording VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, quantity VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE TABLE utilisateur (id INT NOT NULL, email VARCHAR(180) NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, birth_date DATE NOT NULL, phone VARCHAR(255) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON utilisateur (email)');
|
||||
$this->addSql('CREATE TABLE vehicle (id INT NOT NULL, license_plate VARCHAR(255) NOT NULL, brand VARCHAR(255) NOT NULL, model VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE TABLE messenger_messages (id BIGSERIAL NOT NULL, body TEXT NOT NULL, headers TEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, available_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, delivered_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
|
||||
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
|
||||
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
|
||||
$this->addSql('COMMENT ON COLUMN messenger_messages.created_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN messenger_messages.available_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN messenger_messages.delivered_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('CREATE OR REPLACE FUNCTION notify_messenger_messages() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
PERFORM pg_notify(\'messenger_messages\', NEW.queue_name::text);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;');
|
||||
$this->addSql('DROP TRIGGER IF EXISTS notify_trigger ON messenger_messages;');
|
||||
$this->addSql('CREATE TRIGGER notify_trigger AFTER INSERT OR UPDATE ON messenger_messages FOR EACH ROW EXECUTE PROCEDURE notify_messenger_messages();');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('DROP SEQUENCE fault_id_seq CASCADE');
|
||||
$this->addSql('DROP SEQUENCE intervention_id_seq CASCADE');
|
||||
$this->addSql('DROP SEQUENCE skill_id_seq CASCADE');
|
||||
$this->addSql('DROP SEQUENCE stock_id_seq CASCADE');
|
||||
$this->addSql('DROP SEQUENCE utilisateur_id_seq CASCADE');
|
||||
$this->addSql('DROP SEQUENCE vehicle_id_seq CASCADE');
|
||||
$this->addSql('DROP TABLE fault');
|
||||
$this->addSql('DROP TABLE intervention');
|
||||
$this->addSql('DROP TABLE skill');
|
||||
$this->addSql('DROP TABLE stock');
|
||||
$this->addSql('DROP TABLE utilisateur');
|
||||
$this->addSql('DROP TABLE vehicle');
|
||||
$this->addSql('DROP TABLE messenger_messages');
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<?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 Version20250425115854 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('CREATE TABLE intervention_stock (intervention_id INT NOT NULL, stock_id INT NOT NULL, PRIMARY KEY(intervention_id, stock_id))');
|
||||
$this->addSql('CREATE INDEX IDX_3E534AE48EAE3863 ON intervention_stock (intervention_id)');
|
||||
$this->addSql('CREATE INDEX IDX_3E534AE4DCD6110 ON intervention_stock (stock_id)');
|
||||
$this->addSql('CREATE TABLE user_skill (utilisateur_id INT NOT NULL, skill_id INT NOT NULL, PRIMARY KEY(utilisateur_id, skill_id))');
|
||||
$this->addSql('CREATE INDEX IDX_BCFF1F2FFB88E14F ON user_skill (utilisateur_id)');
|
||||
$this->addSql('CREATE INDEX IDX_BCFF1F2F5585C142 ON user_skill (skill_id)');
|
||||
$this->addSql('ALTER TABLE intervention_stock ADD CONSTRAINT FK_3E534AE48EAE3863 FOREIGN KEY (intervention_id) REFERENCES intervention (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE intervention_stock ADD CONSTRAINT FK_3E534AE4DCD6110 FOREIGN KEY (stock_id) REFERENCES stock (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE user_skill ADD CONSTRAINT FK_BCFF1F2FFB88E14F FOREIGN KEY (utilisateur_id) REFERENCES utilisateur (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE user_skill ADD CONSTRAINT FK_BCFF1F2F5585C142 FOREIGN KEY (skill_id) REFERENCES skill (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE intervention ADD user_id INT NOT NULL');
|
||||
$this->addSql('ALTER TABLE intervention ADD fault_id INT NOT NULL');
|
||||
$this->addSql('ALTER TABLE intervention ADD vehicle_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE intervention ADD CONSTRAINT FK_D11814ABA76ED395 FOREIGN KEY (user_id) REFERENCES utilisateur (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE intervention ADD CONSTRAINT FK_D11814AB24171CD3 FOREIGN KEY (fault_id) REFERENCES fault (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE intervention ADD CONSTRAINT FK_D11814AB545317D1 FOREIGN KEY (vehicle_id) REFERENCES vehicle (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_D11814ABA76ED395 ON intervention (user_id)');
|
||||
$this->addSql('CREATE INDEX IDX_D11814AB24171CD3 ON intervention (fault_id)');
|
||||
$this->addSql('CREATE INDEX IDX_D11814AB545317D1 ON intervention (vehicle_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE intervention_stock DROP CONSTRAINT FK_3E534AE48EAE3863');
|
||||
$this->addSql('ALTER TABLE intervention_stock DROP CONSTRAINT FK_3E534AE4DCD6110');
|
||||
$this->addSql('ALTER TABLE user_skill DROP CONSTRAINT FK_BCFF1F2FFB88E14F');
|
||||
$this->addSql('ALTER TABLE user_skill DROP CONSTRAINT FK_BCFF1F2F5585C142');
|
||||
$this->addSql('DROP TABLE intervention_stock');
|
||||
$this->addSql('DROP TABLE user_skill');
|
||||
$this->addSql('ALTER TABLE intervention DROP CONSTRAINT FK_D11814ABA76ED395');
|
||||
$this->addSql('ALTER TABLE intervention DROP CONSTRAINT FK_D11814AB24171CD3');
|
||||
$this->addSql('ALTER TABLE intervention DROP CONSTRAINT FK_D11814AB545317D1');
|
||||
$this->addSql('DROP INDEX IDX_D11814ABA76ED395');
|
||||
$this->addSql('DROP INDEX IDX_D11814AB24171CD3');
|
||||
$this->addSql('DROP INDEX IDX_D11814AB545317D1');
|
||||
$this->addSql('ALTER TABLE intervention DROP user_id');
|
||||
$this->addSql('ALTER TABLE intervention DROP fault_id');
|
||||
$this->addSql('ALTER TABLE intervention DROP vehicle_id');
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
||||
class AuthenticationController extends AbstractController
|
||||
@ -12,11 +12,10 @@ class AuthenticationController extends AbstractController
|
||||
#[Route(path: '/', name: 'app_login')]
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||
{
|
||||
if ($this->getUser()) {
|
||||
return $this->redirectToRoute('dashboard');
|
||||
}
|
||||
|
||||
// get the login error if there is one
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('login/index.html.twig', [
|
||||
@ -28,6 +27,6 @@ class AuthenticationController extends AbstractController
|
||||
#[Route(path: '/logout', name: 'app_logout')]
|
||||
public function logout(): void
|
||||
{
|
||||
throw new \LogicException('Cette méthode est interceptée par Symfony pour déconnecter.');
|
||||
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||
}
|
||||
}
|
||||
}
|
@ -2,80 +2,17 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Repository\InterventionRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/calendrier')]
|
||||
class CalendrierController extends AbstractController
|
||||
{
|
||||
#[Route('/chauffagiste', name: 'app_calendrier_indexChauffagiste')]
|
||||
public function indexChauffagiste(InterventionRepository $interventionRepository): Response
|
||||
#[Route('/calendrier', name: 'app_calendrier')]
|
||||
public function index(): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_CHAUFFAGISTE');
|
||||
|
||||
$interventions = $interventionRepository->findByUser($this->getUser());
|
||||
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'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()])
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('calendrier/indexChauffagiste.html.twig', [
|
||||
'events' => json_encode($events),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/secretaire', name: 'app_calendrier_indexSecretaire')]
|
||||
public function indexSecretaire(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_SECRETAIRE');
|
||||
|
||||
$interventions = $interventionRepository->findAll();
|
||||
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'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()])
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('calendrier/indexSecretaire.html.twig', [
|
||||
'events' => json_encode($events),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/admin', name: 'app_calendrier_index')]
|
||||
public function indexAdmin(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$interventions = $interventionRepository->findAll();
|
||||
|
||||
$events = [];
|
||||
foreach ($interventions as $intervention) {
|
||||
$events[] = [
|
||||
'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()])
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('calendrier/index.html.twig', [
|
||||
'events' => json_encode($events),
|
||||
'controller_name' => 'CalendrierController',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard')]
|
||||
class DashboardController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'dashboard')]
|
||||
#[Route('/admin', name: 'admin_dashboard')]
|
||||
#[Route('/secretaire', name: 'secretaire_dashboard')]
|
||||
#[Route('/chauffagiste', name: 'chauffagiste_dashboard')]
|
||||
public function index(): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_ADMIN')) {
|
||||
return $this->render('dashboard/admin.html.twig');
|
||||
}
|
||||
|
||||
if ($this->isGranted('ROLE_SECRETAIRE')) {
|
||||
return $this->render('dashboard/secretaire.html.twig');
|
||||
}
|
||||
|
||||
if ($this->isGranted('ROLE_CHAUFFAGISTE')) {
|
||||
return $this->render('dashboard/chauffagiste.html.twig');
|
||||
}
|
||||
|
||||
throw $this->createAccessDeniedException('Vous ne pouvez pas accéder à ce tableau de bord.');
|
||||
}
|
||||
}
|
@ -9,15 +9,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/fault')]
|
||||
class FaultController extends AbstractController
|
||||
final class FaultController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_fault_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_fault_index', methods: ['GET'])]
|
||||
public function index(FaultRepository $faultRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('fault/index.html.twig', [
|
||||
'faults' => $faultRepository->findAll(),
|
||||
]);
|
||||
@ -26,8 +25,6 @@ class FaultController extends AbstractController
|
||||
#[Route('/new', name: 'app_fault_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$fault = new Fault();
|
||||
$form = $this->createForm(FaultType::class, $fault);
|
||||
$form->handleRequest($request);
|
||||
@ -35,10 +32,12 @@ class FaultController extends AbstractController
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->persist($fault);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('app_fault_index');
|
||||
|
||||
return $this->redirectToRoute('app_fault_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('fault/new.html.twig', [
|
||||
'fault' => $fault,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
@ -46,7 +45,6 @@ class FaultController extends AbstractController
|
||||
#[Route('/{id}', name: 'app_fault_show', methods: ['GET'])]
|
||||
public function show(Fault $fault): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('fault/show.html.twig', [
|
||||
'fault' => $fault,
|
||||
]);
|
||||
@ -55,39 +53,29 @@ class FaultController extends AbstractController
|
||||
#[Route('/{id}/edit', name: 'app_fault_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Fault $fault, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$form = $this->createForm(FaultType::class, $fault);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('app_fault_index');
|
||||
|
||||
return $this->redirectToRoute('app_fault_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('fault/edit.html.twig', [
|
||||
'form' => $form,
|
||||
'fault' => $fault,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_fault_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Fault $fault, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
if ($this->isCsrfTokenValid('delete'.$fault->getId(), $request->request->get('_token'))) {
|
||||
if ($this->isCsrfTokenValid('delete'.$fault->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($fault);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_fault_index');
|
||||
}
|
||||
|
||||
private function denyUnlessAdminOrSecretaire(): void
|
||||
{
|
||||
if (!$this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_SECRETAIRE')) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
return $this->redirectToRoute('app_fault_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -5,214 +5,77 @@ namespace App\Controller;
|
||||
use App\Entity\Intervention;
|
||||
use App\Form\InterventionType;
|
||||
use App\Repository\InterventionRepository;
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/intervention')]
|
||||
class InterventionController extends AbstractController
|
||||
final class InterventionController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_intervention_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_intervention_index', methods: ['GET'])]
|
||||
public function index(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('intervention/index.html.twig', [
|
||||
'interventions' => $interventionRepository->findAll(),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'app_intervention_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager, InterventionRepository $interventionRepository, UserRepository $userRepository): Response
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$intervention = new Intervention();
|
||||
$users = $userRepository->findAll();
|
||||
|
||||
$form = $this->createForm(InterventionType::class, $intervention, [
|
||||
'users' => $users,
|
||||
]);
|
||||
$form = $this->createForm(InterventionType::class, $intervention);
|
||||
$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();
|
||||
|
||||
return $this->redirectToRoute('app_intervention_index');
|
||||
return $this->redirectToRoute('app_intervention_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('intervention/new.html.twig', [
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}/edit', name: 'app_intervention_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Intervention $intervention, EntityManagerInterface $entityManager, InterventionRepository $interventionRepository, UserRepository $userRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$users = $userRepository->findAll();
|
||||
|
||||
$form = $this->createForm(InterventionType::class, $intervention, [
|
||||
'users' => $users,
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$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('vehicule', $vehicule)
|
||||
->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->render('intervention/edit.html.twig', [
|
||||
'form' => $form,
|
||||
'intervention' => $intervention,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/mes-interventions', name: 'app_intervention_mes', methods: ['GET'])]
|
||||
public function mesInterventions(InterventionRepository $interventionRepository): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_CHAUFFAGISTE');
|
||||
|
||||
$user = $this->getUser();
|
||||
$interventions = $interventionRepository->findBy(['user' => $user]);
|
||||
|
||||
return $this->render('intervention/indexChauffagiste.html.twig', [
|
||||
'interventions' => $interventions,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_intervention_show', methods: ['GET'])]
|
||||
public function show(Intervention $intervention): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_CHAUFFAGISTE')) {
|
||||
if ($intervention->getUser() !== $this->getUser()) {
|
||||
throw $this->createAccessDeniedException('Accès refusé à cette intervention.');
|
||||
}
|
||||
} else {
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
}
|
||||
|
||||
return $this->render('intervention/show.html.twig', [
|
||||
'intervention' => $intervention,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}/edit', name: 'app_intervention_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$form = $this->createForm(InterventionType::class, $intervention);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_intervention_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('intervention/edit.html.twig', [
|
||||
'intervention' => $intervention,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_intervention_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $intervention->getId(), $request->request->get('_token'))) {
|
||||
if ($this->isCsrfTokenValid('delete'.$intervention->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($intervention);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_intervention_index');
|
||||
}
|
||||
|
||||
#[Route('/{id}/remarque', name: 'app_intervention_remarque', methods: ['GET', 'POST'])]
|
||||
public function ajouterRemarque(Request $request, Intervention $intervention, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$user = $this->getUser();
|
||||
if (!$this->isGranted('ROLE_CHAUFFAGISTE') || $intervention->getUser() !== $user) {
|
||||
throw $this->createAccessDeniedException("Vous ne pouvez modifier que vos propres interventions.");
|
||||
}
|
||||
|
||||
$form = $this->createForm(RemarqueType::class, $intervention);
|
||||
$form->handleRequest($request);
|
||||
|
||||
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()]);
|
||||
}
|
||||
|
||||
return $this->render('intervention/remarque.html.twig', [
|
||||
'form' => $form,
|
||||
'intervention' => $intervention,
|
||||
]);
|
||||
}
|
||||
|
||||
private function denyUnlessAdminOrSecretaire(): void
|
||||
{
|
||||
if (!$this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_SECRETAIRE')) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
return $this->redirectToRoute('app_intervention_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/skill')]
|
||||
class SkillController extends AbstractController
|
||||
final class SkillController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_skill_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_skill_index', methods: ['GET'])]
|
||||
public function index(SkillRepository $skillRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('skill/index.html.twig', [
|
||||
'skills' => $skillRepository->findAll(),
|
||||
]);
|
||||
@ -26,8 +25,6 @@ class SkillController extends AbstractController
|
||||
#[Route('/new', name: 'app_skill_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$skill = new Skill();
|
||||
$form = $this->createForm(SkillType::class, $skill);
|
||||
$form->handleRequest($request);
|
||||
@ -36,10 +33,11 @@ class SkillController extends AbstractController
|
||||
$entityManager->persist($skill);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_skill_index');
|
||||
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('skill/new.html.twig', [
|
||||
'skill' => $skill,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
@ -47,7 +45,6 @@ class SkillController extends AbstractController
|
||||
#[Route('/{id}', name: 'app_skill_show', methods: ['GET'])]
|
||||
public function show(Skill $skill): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('skill/show.html.twig', [
|
||||
'skill' => $skill,
|
||||
]);
|
||||
@ -56,40 +53,29 @@ class SkillController extends AbstractController
|
||||
#[Route('/{id}/edit', name: 'app_skill_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Skill $skill, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$form = $this->createForm(SkillType::class, $skill);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_skill_index');
|
||||
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('skill/edit.html.twig', [
|
||||
'form' => $form,
|
||||
'skill' => $skill,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_skill_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Skill $skill, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $skill->getId(), $request->request->get('_token'))) {
|
||||
if ($this->isCsrfTokenValid('delete'.$skill->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($skill);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_skill_index');
|
||||
}
|
||||
|
||||
private function denyUnlessAdminOrSecretaire(): void
|
||||
{
|
||||
if (!$this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_SECRETAIRE')) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/stock')]
|
||||
class StockController extends AbstractController
|
||||
final class StockController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_stock_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_stock_index', methods: ['GET'])]
|
||||
public function index(StockRepository $stockRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('stock/index.html.twig', [
|
||||
'stocks' => $stockRepository->findAll(),
|
||||
]);
|
||||
@ -26,8 +25,6 @@ class StockController extends AbstractController
|
||||
#[Route('/new', name: 'app_stock_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$stock = new Stock();
|
||||
$form = $this->createForm(StockType::class, $stock);
|
||||
$form->handleRequest($request);
|
||||
@ -36,10 +33,11 @@ class StockController extends AbstractController
|
||||
$entityManager->persist($stock);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_stock_index');
|
||||
return $this->redirectToRoute('app_stock_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('stock/new.html.twig', [
|
||||
'stock' => $stock,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
@ -47,7 +45,6 @@ class StockController extends AbstractController
|
||||
#[Route('/{id}', name: 'app_stock_show', methods: ['GET'])]
|
||||
public function show(Stock $stock): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('stock/show.html.twig', [
|
||||
'stock' => $stock,
|
||||
]);
|
||||
@ -56,40 +53,29 @@ class StockController extends AbstractController
|
||||
#[Route('/{id}/edit', name: 'app_stock_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Stock $stock, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$form = $this->createForm(StockType::class, $stock);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_stock_index');
|
||||
return $this->redirectToRoute('app_stock_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('stock/edit.html.twig', [
|
||||
'form' => $form,
|
||||
'stock' => $stock,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_stock_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Stock $stock, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $stock->getId(), $request->request->get('_token'))) {
|
||||
if ($this->isCsrfTokenValid('delete'.$stock->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($stock);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_stock_index');
|
||||
}
|
||||
|
||||
private function denyUnlessAdminOrSecretaire(): void
|
||||
{
|
||||
if (!$this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_SECRETAIRE')) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
return $this->redirectToRoute('app_stock_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -9,14 +9,12 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[IsGranted('ROLE_ADMIN')] // accès global restreint
|
||||
#[Route('/user')]
|
||||
final class UserController extends AbstractController
|
||||
{
|
||||
#[Route('/user', name: 'app_user_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_user_index', methods: ['GET'])]
|
||||
public function index(UserRepository $userRepository): Response
|
||||
{
|
||||
return $this->render('user/index.html.twig', [
|
||||
@ -24,18 +22,14 @@ final class UserController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/user/new', name: 'app_user_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher): Response
|
||||
#[Route('/new', name: 'app_user_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$user = new Utilisateur();
|
||||
$form = $this->createForm(UserType::class, $user);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$plainPassword = $form->get('plainPassword')->getData();
|
||||
$hashedPassword = $passwordHasher->hashPassword($user, $plainPassword);
|
||||
$user->setPassword($hashedPassword);
|
||||
|
||||
$entityManager->persist($user);
|
||||
$entityManager->flush();
|
||||
|
||||
@ -48,7 +42,7 @@ final class UserController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/user/{id}', name: 'app_user_show', methods: ['GET'])]
|
||||
#[Route('/{id}', name: 'app_user_show', methods: ['GET'])]
|
||||
public function show(Utilisateur $user): Response
|
||||
{
|
||||
return $this->render('user/show.html.twig', [
|
||||
@ -56,7 +50,7 @@ final class UserController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/user/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])]
|
||||
#[Route('/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Utilisateur $user, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$form = $this->createForm(UserType::class, $user);
|
||||
@ -74,17 +68,14 @@ final class UserController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/user/{id}', name: 'app_user_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Utilisateur $utilisateur, EntityManagerInterface $entityManager): Response
|
||||
#[Route('/{id}', name: 'app_user_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Utilisateur $user, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isCsrfTokenValid('delete' . $utilisateur->getId(), $request->request->get('_token'))) {
|
||||
$entityManager->remove($utilisateur);
|
||||
if ($this->isCsrfTokenValid('delete'.$user->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($user);
|
||||
$entityManager->flush();
|
||||
$this->addFlash('success', 'Utilisateur supprimé avec succès.');
|
||||
} else {
|
||||
$this->addFlash('error', 'Token CSRF invalide.');
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_user_index');
|
||||
return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[Route('/vehicle')]
|
||||
class VehicleController extends AbstractController
|
||||
final class VehicleController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_vehicle_index', methods: ['GET'])]
|
||||
#[Route(name: 'app_vehicle_index', methods: ['GET'])]
|
||||
public function index(VehicleRepository $vehicleRepository): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('vehicle/index.html.twig', [
|
||||
'vehicles' => $vehicleRepository->findAll(),
|
||||
]);
|
||||
@ -26,8 +25,6 @@ class VehicleController extends AbstractController
|
||||
#[Route('/new', name: 'app_vehicle_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$vehicle = new Vehicle();
|
||||
$form = $this->createForm(VehicleType::class, $vehicle);
|
||||
$form->handleRequest($request);
|
||||
@ -35,10 +32,12 @@ class VehicleController extends AbstractController
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->persist($vehicle);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('app_vehicle_index');
|
||||
|
||||
return $this->redirectToRoute('app_vehicle_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('vehicle/new.html.twig', [
|
||||
'vehicle' => $vehicle,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
@ -46,7 +45,6 @@ class VehicleController extends AbstractController
|
||||
#[Route('/{id}', name: 'app_vehicle_show', methods: ['GET'])]
|
||||
public function show(Vehicle $vehicle): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
return $this->render('vehicle/show.html.twig', [
|
||||
'vehicle' => $vehicle,
|
||||
]);
|
||||
@ -55,39 +53,29 @@ class VehicleController extends AbstractController
|
||||
#[Route('/{id}/edit', name: 'app_vehicle_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Vehicle $vehicle, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
$form = $this->createForm(VehicleType::class, $vehicle);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('app_vehicle_index');
|
||||
|
||||
return $this->redirectToRoute('app_vehicle_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('vehicle/edit.html.twig', [
|
||||
'form' => $form,
|
||||
'vehicle' => $vehicle,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_vehicle_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Vehicle $vehicle, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyUnlessAdminOrSecretaire();
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $vehicle->getId(), $request->request->get('_token'))) {
|
||||
if ($this->isCsrfTokenValid('delete'.$vehicle->getId(), $request->getPayload()->getString('_token'))) {
|
||||
$entityManager->remove($vehicle);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_vehicle_index');
|
||||
}
|
||||
|
||||
private function denyUnlessAdminOrSecretaire(): void
|
||||
{
|
||||
if (!$this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_SECRETAIRE')) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
return $this->redirectToRoute('app_vehicle_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ class Fault
|
||||
public function setWording(string $Wording): static
|
||||
{
|
||||
$this->Wording = $Wording;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -43,6 +44,7 @@ class Fault
|
||||
public function setDescription(string $Description): static
|
||||
{
|
||||
$this->Description = $Description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -1,183 +1,10 @@
|
||||
<?php
|
||||
//
|
||||
//namespace App\Entity;
|
||||
//
|
||||
//use App\Repository\InterventionRepository;
|
||||
//use Doctrine\DBAL\Types\Types;
|
||||
//use Doctrine\ORM\Mapping as ORM;
|
||||
//use Doctrine\Common\Collections\ArrayCollection;
|
||||
//use Doctrine\Common\Collections\Collection;
|
||||
//
|
||||
//#[ORM\Entity(repositoryClass: InterventionRepository::class)]
|
||||
//class Intervention
|
||||
//{
|
||||
// #[ORM\Id]
|
||||
// #[ORM\GeneratedValue]
|
||||
// #[ORM\Column]
|
||||
// private ?int $id = null;
|
||||
//
|
||||
// #[ORM\Column(length: 255)]
|
||||
// private ?string $Wording = null;
|
||||
//
|
||||
// #[ORM\Column(type: Types::DATETIME_MUTABLE)]
|
||||
// private ?\DateTimeInterface $Timestamp = null;
|
||||
//
|
||||
// #[ORM\Column(length: 255)]
|
||||
// private ?string $Description = null;
|
||||
//
|
||||
// #[ORM\Column(length: 255)]
|
||||
// private ?string $Address = null;
|
||||
//
|
||||
// #[ORM\Column(length: 255)]
|
||||
// private ?string $Status = null;
|
||||
//
|
||||
////<<<<<<< HEAD
|
||||
//// #[ORM\ManyToOne(targetEntity: Vehicule::class)]
|
||||
//// private ?Vehicule $vehicule = null;
|
||||
////
|
||||
////=======
|
||||
// #[ORM\ManyToOne(inversedBy: 'interventions')]
|
||||
// #[ORM\JoinColumn(nullable: false)]
|
||||
// private ?Utilisateur $user = null;
|
||||
//
|
||||
// #[ORM\ManyToOne]
|
||||
// #[ORM\JoinColumn(nullable: false)]
|
||||
// private ?Fault $fault = null;
|
||||
//
|
||||
// #[ORM\ManyToOne(inversedBy: 'intervention')]
|
||||
// private ?Vehicle $vehicle = null;
|
||||
//
|
||||
// #[ORM\ManyToMany(targetEntity: Stock::class)]
|
||||
// #[ORM\JoinTable(name: "intervention_stock")]
|
||||
// private Collection $stocks;
|
||||
//
|
||||
// public function __construct()
|
||||
// {
|
||||
// $this->stocks = new ArrayCollection();
|
||||
// }
|
||||
////>>>>>>> 4fc91211f0d814453d2ed97caf6a1d94d709058e
|
||||
//
|
||||
// public function getId(): ?int
|
||||
// {
|
||||
// return $this->id;
|
||||
// }
|
||||
//
|
||||
// public function getWording(): ?string
|
||||
// {
|
||||
// return $this->Wording;
|
||||
// }
|
||||
//
|
||||
// public function setWording(string $Wording): static
|
||||
// {
|
||||
// $this->Wording = $Wording;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getTimestamp(): ?\DateTimeInterface
|
||||
// {
|
||||
// return $this->Timestamp;
|
||||
// }
|
||||
//
|
||||
// public function setTimestamp(\DateTimeInterface $Timestamp): static
|
||||
// {
|
||||
// $this->Timestamp = $Timestamp;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getDescription(): ?string
|
||||
// {
|
||||
// return $this->Description;
|
||||
// }
|
||||
//
|
||||
// public function setDescription(string $Description): static
|
||||
// {
|
||||
// $this->Description = $Description;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getAddress(): ?string
|
||||
// {
|
||||
// return $this->Address;
|
||||
// }
|
||||
//
|
||||
// public function setAddress(string $Address): static
|
||||
// {
|
||||
// $this->Address = $Address;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getStatus(): ?string
|
||||
// {
|
||||
// return $this->Status;
|
||||
// }
|
||||
//
|
||||
// public function setStatus(string $Status): static
|
||||
// {
|
||||
// $this->Status = $Status;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getUser(): ?Utilisateur
|
||||
// {
|
||||
// return $this->user;
|
||||
// }
|
||||
//
|
||||
// public function setUser(?Utilisateur $user): static
|
||||
// {
|
||||
// $this->user = $user;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getFault(): ?Fault
|
||||
// {
|
||||
// return $this->fault;
|
||||
// }
|
||||
//
|
||||
// public function setFault(?Fault $fault): static
|
||||
// {
|
||||
// $this->fault = $fault;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getVehicle(): ?Vehicle
|
||||
// {
|
||||
// return $this->vehicle;
|
||||
// }
|
||||
//
|
||||
// public function setVehicle(?Vehicle $vehicle): static
|
||||
// {
|
||||
// $this->vehicle = $vehicle;
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function getStocks(): Collection
|
||||
// {
|
||||
// return $this->stocks;
|
||||
// }
|
||||
//
|
||||
// public function addStock(Stock $stock): static
|
||||
// {
|
||||
// if (!$this->stocks->contains($stock)) {
|
||||
// $this->stocks[] = $stock;
|
||||
// }
|
||||
// return $this;
|
||||
// }
|
||||
//
|
||||
// public function removeStock(Stock $stock): static
|
||||
// {
|
||||
// $this->stocks->removeElement($stock);
|
||||
// return $this;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\InterventionRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
#[ORM\Entity(repositoryClass: InterventionRepository::class)]
|
||||
class Intervention
|
||||
@ -202,33 +29,6 @@ class Intervention
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $Status = null;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $Remarque = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'interventions')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Utilisateur $user = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Fault $fault = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'intervention')]
|
||||
private ?Vehicle $vehicle = null;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Stock::class)]
|
||||
#[ORM\JoinTable(name: "intervention_stock")]
|
||||
private Collection $stocks;
|
||||
|
||||
// Ajout de la propriété StartDate
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
private ?\DateTimeInterface $startDate = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->stocks = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -242,6 +42,7 @@ class Intervention
|
||||
public function setWording(string $Wording): static
|
||||
{
|
||||
$this->Wording = $Wording;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -253,6 +54,7 @@ class Intervention
|
||||
public function setTimestamp(\DateTimeInterface $Timestamp): static
|
||||
{
|
||||
$this->Timestamp = $Timestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -264,6 +66,7 @@ class Intervention
|
||||
public function setDescription(string $Description): static
|
||||
{
|
||||
$this->Description = $Description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -275,6 +78,7 @@ class Intervention
|
||||
public function setAddress(string $Address): static
|
||||
{
|
||||
$this->Address = $Address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -286,87 +90,7 @@ class Intervention
|
||||
public function setStatus(string $Status): static
|
||||
{
|
||||
$this->Status = $Status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUser(): ?Utilisateur
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(?Utilisateur $user): static
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFault(): ?Fault
|
||||
{
|
||||
return $this->fault;
|
||||
}
|
||||
|
||||
public function setFault(?Fault $fault): static
|
||||
{
|
||||
$this->fault = $fault;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVehicle(): ?Vehicle
|
||||
{
|
||||
return $this->vehicle;
|
||||
}
|
||||
|
||||
public function setVehicle(?Vehicle $vehicle): static
|
||||
{
|
||||
$this->vehicle = $vehicle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStocks(): Collection
|
||||
{
|
||||
return $this->stocks;
|
||||
}
|
||||
|
||||
public function addStock(Stock $stock): static
|
||||
{
|
||||
if (!$this->stocks->contains($stock)) {
|
||||
$this->stocks[] = $stock;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeStock(Stock $stock): static
|
||||
{
|
||||
$this->stocks->removeElement($stock);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Ajout de la méthode getStartDate
|
||||
public function getStartDate(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function setStartDate(\DateTimeInterface $startDate): static
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Ajout de la méthode getTitle()
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->Wording;
|
||||
}
|
||||
|
||||
public function getRemarque(): ?string
|
||||
{
|
||||
return $this->Remarque;
|
||||
}
|
||||
|
||||
public function setRemarque(?string $Remarque): void
|
||||
{
|
||||
$this->Remarque = $Remarque;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,6 @@ namespace App\Entity;
|
||||
|
||||
use App\Repository\SkillRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
#[ORM\Entity(repositoryClass: SkillRepository::class)]
|
||||
class Skill
|
||||
@ -21,14 +19,6 @@ class Skill
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $Description = null;
|
||||
|
||||
#[ORM\ManyToMany(mappedBy: 'skills', targetEntity: Utilisateur::class)]
|
||||
private Collection $users;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->users = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -42,6 +32,7 @@ class Skill
|
||||
public function setWording(string $Wording): static
|
||||
{
|
||||
$this->Wording = $Wording;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -53,28 +44,7 @@ class Skill
|
||||
public function setDescription(string $Description): static
|
||||
{
|
||||
$this->Description = $Description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUsers(): Collection
|
||||
{
|
||||
return $this->users;
|
||||
}
|
||||
|
||||
public function addUser(Utilisateur $user): static
|
||||
{
|
||||
if (!$this->users->contains($user)) {
|
||||
$this->users[] = $user;
|
||||
$user->addSkill($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeUser(Utilisateur $user): static
|
||||
{
|
||||
if ($this->users->removeElement($user)) {
|
||||
$user->removeSkill($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ namespace App\Entity;
|
||||
|
||||
use App\Repository\StockRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
#[ORM\Entity(repositoryClass: StockRepository::class)]
|
||||
class Stock
|
||||
@ -24,14 +22,6 @@ class Stock
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $Quantity = null;
|
||||
|
||||
#[ORM\ManyToMany(mappedBy: 'stocks', targetEntity: Intervention::class)]
|
||||
private Collection $interventions;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->interventions = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -45,6 +35,7 @@ class Stock
|
||||
public function setWording(string $Wording): static
|
||||
{
|
||||
$this->Wording = $Wording;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -56,6 +47,7 @@ class Stock
|
||||
public function setDescription(string $Description): static
|
||||
{
|
||||
$this->Description = $Description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -67,28 +59,7 @@ class Stock
|
||||
public function setQuantity(string $Quantity): static
|
||||
{
|
||||
$this->Quantity = $Quantity;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInterventions(): Collection
|
||||
{
|
||||
return $this->interventions;
|
||||
}
|
||||
|
||||
public function addIntervention(Intervention $intervention): static
|
||||
{
|
||||
if (!$this->interventions->contains($intervention)) {
|
||||
$this->interventions[] = $intervention;
|
||||
$intervention->addStock($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeIntervention(Intervention $intervention): static
|
||||
{
|
||||
if ($this->interventions->removeElement($intervention)) {
|
||||
$intervention->removeStock($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ namespace App\Entity;
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
@ -33,33 +31,87 @@ class Utilisateur implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $Phone = null;
|
||||
|
||||
/**
|
||||
* @var list<string> The user roles
|
||||
*/
|
||||
#[ORM\Column]
|
||||
private array $roles = [];
|
||||
|
||||
/**
|
||||
* @var string The hashed password
|
||||
*/
|
||||
#[ORM\Column]
|
||||
private ?string $password = null;
|
||||
|
||||
private ?string $plainPassword = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'user', targetEntity: Intervention::class)]
|
||||
private Collection $interventions;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Skill::class)]
|
||||
#[ORM\JoinTable(name: "user_skill")]
|
||||
private Collection $skills;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->interventions = new ArrayCollection();
|
||||
$this->skills = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getBirthDate(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->BirthDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTimeInterface|null $BirthDate
|
||||
*/
|
||||
public function setBirthDate(?\DateTimeInterface $BirthDate): void
|
||||
{
|
||||
$this->BirthDate = $BirthDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLastName(): ?string
|
||||
{
|
||||
return $this->LastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $LastName
|
||||
*/
|
||||
public function setLastName(?string $LastName): void
|
||||
{
|
||||
$this->LastName = $LastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFirstName(): ?string
|
||||
{
|
||||
return $this->FirstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $FirstName
|
||||
*/
|
||||
public function setFirstName(?string $FirstName): void
|
||||
{
|
||||
$this->FirstName = $FirstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPhone(): ?string
|
||||
{
|
||||
return $this->Phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $Phone
|
||||
*/
|
||||
public function setPhone(?string $Phone): void
|
||||
{
|
||||
$this->Phone = $Phone;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
@ -68,63 +120,47 @@ class Utilisateur implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
public function setEmail(string $email): static
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstName(): ?string
|
||||
/**
|
||||
* A visual identifier that represents this user.
|
||||
*
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return $this->FirstName;
|
||||
}
|
||||
|
||||
public function setFirstName(?string $FirstName): void
|
||||
{
|
||||
$this->FirstName = $FirstName;
|
||||
}
|
||||
|
||||
public function getLastName(): ?string
|
||||
{
|
||||
return $this->LastName;
|
||||
}
|
||||
|
||||
public function setLastName(?string $LastName): void
|
||||
{
|
||||
$this->LastName = $LastName;
|
||||
}
|
||||
|
||||
public function getBirthDate(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->BirthDate;
|
||||
}
|
||||
|
||||
public function setBirthDate(?\DateTimeInterface $BirthDate): void
|
||||
{
|
||||
$this->BirthDate = $BirthDate;
|
||||
}
|
||||
|
||||
public function getPhone(): ?string
|
||||
{
|
||||
return $this->Phone;
|
||||
}
|
||||
|
||||
public function setPhone(?string $Phone): void
|
||||
{
|
||||
$this->Phone = $Phone;
|
||||
return (string) $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UserInterface
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getRoles(): array
|
||||
{
|
||||
$roles = $this->roles;
|
||||
// guarantee every user at least has ROLE_USER
|
||||
$roles[] = 'ROLE_USER';
|
||||
|
||||
return array_unique($roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $roles
|
||||
*/
|
||||
public function setRoles(array $roles): static
|
||||
{
|
||||
$this->roles = $roles;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PasswordAuthenticatedUserInterface
|
||||
*/
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return $this->password;
|
||||
@ -133,69 +169,16 @@ class Utilisateur implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
public function setPassword(string $password): static
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return (string) $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function eraseCredentials(): void
|
||||
{
|
||||
$this->plainPassword = null;
|
||||
}
|
||||
|
||||
public function getPlainPassword(): ?string
|
||||
{
|
||||
return $this->plainPassword;
|
||||
}
|
||||
|
||||
public function setPlainPassword(?string $plainPassword): void
|
||||
{
|
||||
$this->plainPassword = $plainPassword;
|
||||
}
|
||||
|
||||
public function getInterventions(): Collection
|
||||
{
|
||||
return $this->interventions;
|
||||
}
|
||||
|
||||
public function addIntervention(Intervention $intervention): static
|
||||
{
|
||||
if (!$this->interventions->contains($intervention)) {
|
||||
$this->interventions[] = $intervention;
|
||||
$intervention->setUser($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeIntervention(Intervention $intervention): static
|
||||
{
|
||||
if ($this->interventions->removeElement($intervention)) {
|
||||
if ($intervention->getUser() === $this) {
|
||||
$intervention->setUser(null);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSkills(): Collection
|
||||
{
|
||||
return $this->skills;
|
||||
}
|
||||
|
||||
public function addSkill(Skill $skill): static
|
||||
{
|
||||
if (!$this->skills->contains($skill)) {
|
||||
$this->skills[] = $skill;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSkill(Skill $skill): static
|
||||
{
|
||||
$this->skills->removeElement($skill);
|
||||
return $this;
|
||||
// If you store any temporary, sensitive data on the user, clear it here
|
||||
// $this->plainPassword = null;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ namespace App\Entity;
|
||||
|
||||
use App\Repository\VehicleRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
#[ORM\Entity(repositoryClass: VehicleRepository::class)]
|
||||
class Vehicle
|
||||
@ -24,14 +22,6 @@ class Vehicle
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $Model = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'vehicle', targetEntity: Intervention::class)]
|
||||
private Collection $intervention;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->intervention = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -45,6 +35,7 @@ class Vehicle
|
||||
public function setLicensePlate(string $LicensePlate): static
|
||||
{
|
||||
$this->LicensePlate = $LicensePlate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -56,6 +47,7 @@ class Vehicle
|
||||
public function setBrand(string $Brand): static
|
||||
{
|
||||
$this->Brand = $Brand;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -68,28 +60,4 @@ class Vehicle
|
||||
{
|
||||
$this->Model = $Model;
|
||||
}
|
||||
|
||||
public function getIntervention(): Collection
|
||||
{
|
||||
return $this->intervention;
|
||||
}
|
||||
|
||||
public function addIntervention(Intervention $intervention): static
|
||||
{
|
||||
if (!$this->intervention->contains($intervention)) {
|
||||
$this->intervention[] = $intervention;
|
||||
$intervention->setVehicle($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeIntervention(Intervention $intervention): static
|
||||
{
|
||||
if ($this->intervention->removeElement($intervention)) {
|
||||
if ($intervention->getVehicle() === $this) {
|
||||
$intervention->setVehicle(null);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Fault;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@ -15,7 +14,6 @@ class FaultType extends AbstractType
|
||||
{
|
||||
$builder
|
||||
->add('Wording', TextType::class)
|
||||
->add('Description', TextType::class)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,9 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Fault;
|
||||
use App\Entity\Intervention;
|
||||
use App\Entity\Stock;
|
||||
use App\Entity\Utilisateur;
|
||||
use App\Entity\Vehicle;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
@ -18,56 +13,21 @@ class InterventionType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$intervention = $builder->getData();
|
||||
$allUsers = $options['users'] ?? [];
|
||||
|
||||
$chauffagistes = array_filter($allUsers, fn(Utilisateur $user) =>
|
||||
in_array('ROLE_CHAUFFAGISTE', $user->getRoles(), true)
|
||||
);
|
||||
|
||||
$currentUser = $intervention->getUser();
|
||||
if ($currentUser && !in_array($currentUser, $chauffagistes, true)) {
|
||||
$chauffagistes[] = $currentUser;
|
||||
}
|
||||
|
||||
$builder
|
||||
->add('Wording', TextType::class)
|
||||
->add('Timestamp', DateTimeType::class, [
|
||||
->add('Timestamp', DateType::class, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('Description', TextType::class)
|
||||
->add('Address', TextType::class)
|
||||
->add('Status', TextType::class)
|
||||
->add('user', EntityType::class, [
|
||||
'class' => Utilisateur::class,
|
||||
'choice_label' => fn(Utilisateur $user) => $user->getFirstName() . ' ' . $user->getLastName(),
|
||||
'choices' => $chauffagistes,
|
||||
'label' => 'Chauffagiste assigné',
|
||||
'placeholder' => 'Sélectionnez un chauffagiste',
|
||||
'required' => true,
|
||||
])
|
||||
->add('fault', EntityType::class, [
|
||||
'class' => Fault::class,
|
||||
'choice_label' => 'Wording',
|
||||
])
|
||||
->add('vehicle', EntityType::class, [
|
||||
'class' => Vehicle::class,
|
||||
'choice_label' => 'LicensePlate',
|
||||
'required' => false,
|
||||
])
|
||||
->add('stocks', EntityType::class, [
|
||||
'class' => Stock::class,
|
||||
'choice_label' => 'Wording',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Intervention::class,
|
||||
'users' => [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use App\Entity\Intervention;
|
||||
|
||||
class RemarqueType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('Remarque', TextareaType::class, [
|
||||
'label' => 'Ajouter une remarque',
|
||||
'attr' => [
|
||||
'rows' => 5,
|
||||
'placeholder' => 'Renseignez les observations de l’intervention…'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Intervention::class,
|
||||
]);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ class SkillType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('Wording', TextType::class)
|
||||
->add('Wording',TextType::class)
|
||||
->add('Description', TextType::class)
|
||||
;
|
||||
}
|
||||
|
@ -2,13 +2,10 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Skill;
|
||||
use App\Entity\Utilisateur;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
@ -26,26 +23,9 @@ class UserType extends AbstractType
|
||||
])
|
||||
->add('Phone', TextType::class)
|
||||
->add('roles', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'Secretaire' => 'ROLE_SECRETAIRE',
|
||||
'Chauffagiste' => 'ROLE_CHAUFFAGISTE',
|
||||
'Admin' => 'ROLE_ADMIN', // Ajouté si besoin de créer des admins
|
||||
],
|
||||
'multiple' => true,
|
||||
'expanded' => true, // pour avoir des cases à cocher
|
||||
])
|
||||
->add('skills', EntityType::class, [
|
||||
'class' => Skill::class,
|
||||
'choice_label' => 'Wording',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'required' => false,
|
||||
])
|
||||
->add('plainPassword', PasswordType::class, [
|
||||
'mapped' => false,
|
||||
'required' => true,
|
||||
'label' => 'Mot de passe',
|
||||
])
|
||||
->add('password', TextType::class)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ class VehicleType extends AbstractType
|
||||
$builder
|
||||
->add('LicensePlate', TextType::class)
|
||||
->add('Brand', TextType::class)
|
||||
->add('Model', TextType::class)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
|
||||
|
||||
class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
|
||||
{
|
||||
private RouterInterface $router;
|
||||
|
||||
public function __construct(RouterInterface $router)
|
||||
{
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token): RedirectResponse
|
||||
{
|
||||
$user = $token->getUser();
|
||||
$roles = $user->getRoles();
|
||||
|
||||
return match (true) {
|
||||
in_array('ROLE_ADMIN', $roles) => new RedirectResponse($this->router->generate('admin_dashboard')),
|
||||
in_array('ROLE_SECRETAIRE', $roles) => new RedirectResponse($this->router->generate('secretaire_dashboard')),
|
||||
in_array('ROLE_CHAUFFAGISTE', $roles) => new RedirectResponse($this->router->generate('chauffagiste_dashboard')),
|
||||
default => new RedirectResponse($this->router->generate('_login')),
|
||||
};
|
||||
}
|
||||
}
|
@ -2,131 +2,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Mon App Symfony{% endblock %}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
|
||||
{% block stylesheets %}
|
||||
{% endblock %}
|
||||
|
||||
header {
|
||||
background-color: #222;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
nav {
|
||||
background-color: #eee;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav li a {
|
||||
text-decoration: none;
|
||||
color: #0077cc;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
nav li a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.role-badge {
|
||||
background: #ddd;
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 4px;
|
||||
margin-right: 0.3rem;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: 1px solid white;
|
||||
padding: 0.3rem 0.8rem;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background-color: white;
|
||||
color: #222;
|
||||
}
|
||||
</style>
|
||||
{% block stylesheets %}{% endblock %}
|
||||
|
||||
<!-- FullCalendar pour faire un calendrier dynamique -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.css" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.js"></script>
|
||||
{% block javascripts %}
|
||||
{% block importmap %}{{ importmap('app') }}{% endblock %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% if app.user %}
|
||||
<header>
|
||||
<div class="user-info">
|
||||
<div>
|
||||
<strong>Connecté en tant que</strong> {{ app.user.email }}<br>
|
||||
</div>
|
||||
<a href="{{ path('app_logout') }}" class="logout-btn">Déconnexion</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav>
|
||||
<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_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 %}
|
||||
|
||||
{% if is_granted('ROLE_CHAUFFAGISTE') %}
|
||||
<li><a href="{{ path('chauffagiste_dashboard') }}">Dashboard Chauffagiste</a></li>
|
||||
<li><a href="{{ path('app_intervention_mes') }}">Mes interventions</a></li>
|
||||
<li><a href="{{ path('app_calendrier_indexChauffagiste') }}">Mon planning</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<div class="content">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block javascripts %}{% endblock %}
|
||||
{% block body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -1,28 +1,55 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Authentification{% endblock %}</title>
|
||||
<link href="{{ asset('styles/css/calendrier.css') }}" rel="stylesheet">
|
||||
{% block stylesheets %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
{% block title %}Calendrier des interventions{% endblock %}
|
||||
<body>
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/6.png') }}">
|
||||
</div>
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/3.png') }}">
|
||||
</div>
|
||||
<span>Create Intervention</span>
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/4.png') }}">
|
||||
</div>
|
||||
<span>Choose heating engineer</span>
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/5.png') }}">
|
||||
</div>
|
||||
<span>Modify Intervention</span>
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/7.png') }}">
|
||||
</div>
|
||||
<span>Surname Name</span>
|
||||
|
||||
{% block body %}
|
||||
<h1>📅 Calendrier des interventions</h1>
|
||||
<div class="sidebar-button">
|
||||
<img class="logoEmail" src="{{ asset('styles/image/LogoHegreConfort_SansFond.png') }}">
|
||||
</div>
|
||||
|
||||
<div id="calendar"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'dayGridMonth',
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
<div class="main-content">
|
||||
<div class="calendar-header" style="gap: 50px">
|
||||
<div class="day-header">Mo</div>
|
||||
<div class="day-header">Tu</div>
|
||||
<div class="day-header">We</div>
|
||||
<div class="day-header">Th</div>
|
||||
<div class="day-header">Fr</div>
|
||||
<div class="day-header">Sa</div>
|
||||
<div class="day-header">Su</div>
|
||||
</div>
|
||||
<div class="calendar-title">Calendar</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,28 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Mon calendrier d'interventions{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>📅 Mon calendrier d'interventions</h1>
|
||||
|
||||
<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',
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,28 +1,20 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Calendrier des interventions{% endblock %}
|
||||
{% block title %}Hello CalendrierController!{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>📅 Calendrier des interventions</h1>
|
||||
<style>
|
||||
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
|
||||
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
|
||||
</style>
|
||||
|
||||
<div id="calendar"></div>
|
||||
<div class="example-wrapper">
|
||||
<h1>Hello {{ controller_name }}! ✅</h1>
|
||||
|
||||
<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',
|
||||
locale: 'fr',
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
},
|
||||
events: {{ events|raw }}
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
</script>
|
||||
This friendly message is coming from:
|
||||
<ul>
|
||||
<li>Your controller at <code>/home/allarda@stsio.lan/Test/HegreEtConfort/src/Controller/CalendrierController.php</code></li>
|
||||
<li>Your template at <code>/home/allarda@stsio.lan/Test/HegreEtConfort/templates/calendrier/index.html.twig</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -1,15 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Dashboard Administrateur{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">👑 Bienvenue {{ app.user.FirstName }} sur le Dashboard Administrateur</h1>
|
||||
|
||||
<p>Vous êtes connecté avec les rôles :
|
||||
{% for role in app.user.roles %}
|
||||
<span class="badge bg-primary">{{ role }}</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p class="text-muted">Utilisez le menu en haut pour accéder aux fonctionnalités.</p>
|
||||
{% endblock %}
|
@ -1,15 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Dashboard Chauffagiste{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🔧 Bonjour {{ app.user.FirstName }}, bienvenue sur ton espace</h1>
|
||||
|
||||
<p>Rôle :
|
||||
{% for role in app.user.roles %}
|
||||
<span class="badge bg-success">{{ role }}</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p class="text-muted">Retrouvez votre planning, vos interventions et vos outils dans le menu ci-dessus.</p>
|
||||
{% endblock %}
|
@ -1,15 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Dashboard Secrétaire{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🗂️ Bienvenue {{ app.user.FirstName }} sur le Dashboard Secrétaire</h1>
|
||||
|
||||
<p>Vous êtes connectée avec les rôles :
|
||||
{% for role in app.user.roles %}
|
||||
<span class="badge bg-secondary">{{ role }}</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p class="text-muted">Utilisez le menu pour créer des interventions, gérer les chauffagistes, etc.</p>
|
||||
{% endblock %}
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier la panne{% endblock %}
|
||||
{% block title %}Edit Fault{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier une panne</h1>
|
||||
<h1>Edit Fault</h1>
|
||||
|
||||
{{ include('fault/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('fault/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_fault_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
{{ include('fault/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_fault_index') }}">back to list</a>
|
||||
|
||||
{{ include('fault/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,37 +1,35 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Liste des pannes{% endblock %}
|
||||
{% block title %}Fault index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">📋 Liste des pannes enregistrées</h1>
|
||||
<h1>Fault index</h1>
|
||||
|
||||
<table class="table table-striped table-bordered align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nom</th>
|
||||
<th>Description</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Wording</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for fault in faults %}
|
||||
<tr>
|
||||
<td>{{ fault.id }}</td>
|
||||
<td>{{ fault.Wording }}</td>
|
||||
<td>{{ fault.Description }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ path('app_fault_show', {'id': fault.id}) }}" class="btn btn-sm btn-info">👁️ Voir</a>
|
||||
<a href="{{ path('app_fault_edit', {'id': fault.id}) }}" class="btn btn-sm btn-warning">✏️ Modifier</a>
|
||||
<td>
|
||||
<a href="{{ path('app_fault_show', {'id': fault.id}) }}">show</a>
|
||||
<a href="{{ path('app_fault_edit', {'id': fault.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted">Aucune panne trouvée.</td>
|
||||
<td colspan="3">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_fault_new') }}" class="btn btn-success mt-3">➕ Ajouter une nouvelle panne</a>
|
||||
<a href="{{ path('app_fault_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,13 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Créer une panne{% endblock %}
|
||||
{% block title %}New Fault{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Ajouter une nouvelle panne</h1>
|
||||
<h1>Create new Fault</h1>
|
||||
|
||||
{{ include('fault/_form.html.twig') }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_fault_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
</div>
|
||||
<a href="{{ path('app_fault_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
@ -1,30 +1,26 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Détail de la panne{% endblock %}
|
||||
{% block title %}Fault{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🔍 Détails de la panne</h1>
|
||||
<h1>Fault</h1>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<td>{{ fault.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<td>{{ fault.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ fault.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ fault.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Wording</th>
|
||||
<td>{{ fault.Wording }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_fault_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
<a href="{{ path('app_fault_edit', {'id': fault.id}) }}" class="btn btn-warning">✏️ Modifier</a>
|
||||
{{ include('fault/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_fault_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_fault_edit', {'id': fault.id}) }}">edit</a>
|
||||
|
||||
{{ include('fault/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,59 +1,4 @@
|
||||
{{ form_start(form) }}
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.Wording, 'Nom de l\'intervention') }}
|
||||
{{ form_widget(form.Wording, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.Wording) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.Timestamp, 'Date') }}
|
||||
{{ form_widget(form.Timestamp, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.Timestamp) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.Description, 'Description') }}
|
||||
{{ form_widget(form.Description, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.Description) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.Address, 'Adresse') }}
|
||||
{{ form_widget(form.Address, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.Address) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.Status, 'Statut') }}
|
||||
{{ form_widget(form.Status, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.Status) }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form_label(form.fault, 'Panne') }}
|
||||
{{ form_widget(form.fault, {'attr': {'class': 'form-control'}}) }}
|
||||
{{ form_errors(form.fault) }}
|
||||
</div>
|
||||
|
||||
<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_widget(form) }}
|
||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
||||
{{ form_end(form) }}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier une intervention{% endblock %}
|
||||
{% block title %}Edit Intervention{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier l'intervention</h1>
|
||||
<h1>Edit Intervention</h1>
|
||||
|
||||
{{ include('intervention/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('intervention/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_intervention_index') }}" class="btn btn-secondary">← Retour à la liste des interventions</a>
|
||||
{{ include('intervention/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_intervention_index') }}">back to list</a>
|
||||
|
||||
{{ include('intervention/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,57 +1,43 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Liste des interventions{% endblock %}
|
||||
{% block title %}Intervention index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Liste des interventions</h1>
|
||||
<h1>Intervention index</h1>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Nom</th>
|
||||
<th>Chauffagiste</th>
|
||||
<th>Véhicule</th>
|
||||
<th>Panne</th>
|
||||
<th>Date & Heure</th>
|
||||
<th>Statut</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Wording</th>
|
||||
<th>Timestamp</th>
|
||||
<th>Description</th>
|
||||
<th>Address</th>
|
||||
<th>Status</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for intervention in interventions %}
|
||||
<tr>
|
||||
<td>{{ intervention.id }}</td>
|
||||
<td>{{ intervention.Wording }}</td>
|
||||
<td>
|
||||
{{ intervention.user ? intervention.user.FirstName ~ ' ' ~ intervention.user.LastName : 'Non assigné' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ intervention.vehicle ? intervention.vehicle.LicensePlate : 'Aucun véhicule' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ intervention.fault ? intervention.fault.Wording : 'Non précisé' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ intervention.Timestamp ? intervention.Timestamp|date('Y-m-d H:i') : '' }}
|
||||
</td>
|
||||
<td>{{ intervention.Timestamp ? intervention.Timestamp|date('Y-m-d H:i:s') : '' }}</td>
|
||||
<td>{{ intervention.Description }}</td>
|
||||
<td>{{ intervention.Address }}</td>
|
||||
<td>{{ intervention.Status }}</td>
|
||||
<td>
|
||||
<a href="{{ path('app_intervention_show', {'id': intervention.id}) }}" class="btn btn-info btn-sm">Voir</a>
|
||||
<a href="{{ path('app_intervention_edit', {'id': intervention.id}) }}" class="btn btn-secondary btn-sm">Modifier</a>
|
||||
<a href="{{ path('app_intervention_show', {'id': intervention.id}) }}">show</a>
|
||||
<a href="{{ path('app_intervention_edit', {'id': intervention.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="8">Aucune intervention trouvée</td>
|
||||
<td colspan="7">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_intervention_new') }}" class="btn btn-success">Créer une nouvelle intervention</a>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_calendrier_index') }}" class="btn btn-secondary">← Retour au calendrier</a>
|
||||
</div>
|
||||
<a href="{{ path('app_intervention_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,38 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Mes interventions{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>📋 Mes interventions</h1>
|
||||
|
||||
{% if interventions is not empty %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Description</th>
|
||||
<th>Adresse</th>
|
||||
<th>Statut</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for intervention in interventions %}
|
||||
<tr>
|
||||
<td>{{ intervention.Timestamp ? intervention.Timestamp|date('d/m/Y H:i') : '' }}</td>
|
||||
<td>{{ intervention.Description }}</td>
|
||||
<td>{{ intervention.Address }}</td>
|
||||
<td>{{ intervention.Status }}</td>
|
||||
<td>
|
||||
<a href="{{ path('app_intervention_show', {'id': intervention.id}) }}" class="btn btn-primary btn-sm">
|
||||
Voir
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>Vous n’avez aucune intervention assignée.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -1,11 +1,79 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr, en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Créer une intervention</title>
|
||||
<link href="{{ asset('styles/css/intervention.css') }}" rel='stylesheet'>
|
||||
<link rel="icon"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
{% block title %}Nouvelle intervention{% endblock %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Créer une nouvelle intervention</h1>
|
||||
</head>
|
||||
<body>
|
||||
<div class="background"></div>
|
||||
<img class="logoCalendar" src="{{ asset('styles/image/calendar.png') }}" alt="Logo Calendrier">
|
||||
<a href="{{ path('app_intervention_index') }}" class="intervention">Créer une intervention</a>
|
||||
<img class="logoChauffagiste" src="{{ asset('styles/image/chauffagiste.png') }}" alt="Logo Chauffagiste">
|
||||
<h1 class="chauffagiste">Choisissez un chauffagiste</h1>
|
||||
<img class="logoModifier" src="{{ asset('styles/image/modifier.png') }}">
|
||||
<h1 class="modifier">Modifier l'intervention</h1>
|
||||
<img class="logoHegre" src="{{ asset('styles/image/LogoHegreConfort_SansFond.png') }}">
|
||||
|
||||
<div class="background-intervention">
|
||||
{{ include('intervention/_form.html.twig') }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
<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>
|
||||
<input type="checkbox" name="vehicule1" id="vehicule1">
|
||||
<label for=”vehicule1” id="oui"> Oui </label>
|
||||
<input type="checkbox" name="vehicule2" id="vehicule2">
|
||||
<label for=”vehicule2” id="non"> Non </label>
|
||||
|
||||
<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') }} -->
|
||||
|
||||
<a href="{{ path('app_intervention_index') }}" id="liste">Retour à la liste</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,18 +0,0 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Ajouter une remarque{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">📝 Ajouter une remarque à l'intervention #{{ intervention.id }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_widget(form) }}
|
||||
<button class="btn btn-primary mt-3">Enregistrer la remarque</button>
|
||||
{{ form_end(form) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_intervention_show', {'id': intervention.id}) }}" class="btn btn-secondary">
|
||||
← Retour à l'intervention
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
@ -3,75 +3,40 @@
|
||||
{% block title %}Intervention{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Détails de l'Intervention</h1>
|
||||
<h1>Intervention</h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ intervention.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nom de l'intervention</th>
|
||||
<td>{{ intervention.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date & Heure</th>
|
||||
<td>{{ intervention.Timestamp ? intervention.Timestamp|date('Y-m-d H:i') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ intervention.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Adresse</th>
|
||||
<td>{{ intervention.Address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Statut</th>
|
||||
<td>{{ intervention.Status }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Chauffagiste</th>
|
||||
<td>
|
||||
{{ intervention.user ? intervention.user.FirstName ~ ' ' ~ intervention.user.LastName : 'Non assigné' }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Panne</th>
|
||||
<td>
|
||||
{{ intervention.fault ? intervention.fault.Wording : 'Non précisé' }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Véhicule</th>
|
||||
<td>
|
||||
{{ intervention.vehicle ? intervention.vehicle.LicensePlate : 'Aucun véhicule associé' }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Pièces détachées utilisées</th>
|
||||
<td>
|
||||
{% if intervention.stocks|length > 0 %}
|
||||
<ul>
|
||||
{% for stock in intervention.stocks %}
|
||||
<li>{{ stock.Wording }} (Quantité: {{ stock.Quantity }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
Aucune pièce utilisée
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ intervention.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Wording</th>
|
||||
<td>{{ intervention.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<td>{{ intervention.Timestamp ? intervention.Timestamp|date('Y-m-d H:i:s') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ intervention.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<td>{{ intervention.Address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td>{{ intervention.Status }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% if is_granted('ROLE_CHAUFFAGISTE') and intervention.user == app.user %}
|
||||
<a href="{{ path('app_intervention_remarque', {'id': intervention.id}) }}" class="btn btn-outline-primary">
|
||||
📝 Ajouter une remarque
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{{ path('app_intervention_index') }}" class="btn btn-primary">Retour à la liste</a>
|
||||
<a href="{{ path('app_intervention_edit', {'id': intervention.id}) }}" class="btn btn-warning">Modifier</a>
|
||||
|
||||
<a href="{{ path('app_intervention_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_intervention_edit', {'id': intervention.id}) }}">edit</a>
|
||||
|
||||
{{ include('intervention/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -24,8 +24,7 @@
|
||||
|
||||
<img class="logoProfile" src="{{ asset('styles/image/profile.png') }}" alt="Logo Profil">
|
||||
<img class="logoPassword" src="{{ asset('styles/image/password.png') }}" alt="Logo Password">
|
||||
|
||||
<form method="post" action="{{ path('app_login') }}">
|
||||
<form method="post">
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||
{% endif %}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier une compétence{% endblock %}
|
||||
{% block title %}Edit Skill{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier une compétence</h1>
|
||||
<h1>Edit Skill</h1>
|
||||
|
||||
{{ include('skill/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('skill/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_skill_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
{{ include('skill/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_skill_index') }}">back to list</a>
|
||||
|
||||
{{ include('skill/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,18 +1,18 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Compétences disponibles{% endblock %}
|
||||
{% block title %}Skill index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">📘 Liste des compétences</h1>
|
||||
<h1>Skill index</h1>
|
||||
|
||||
<table class="table table-striped table-bordered align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nom</th>
|
||||
<th>Description</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Wording</th>
|
||||
<th>Description</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for skill in skills %}
|
||||
@ -20,18 +20,18 @@
|
||||
<td>{{ skill.id }}</td>
|
||||
<td>{{ skill.Wording }}</td>
|
||||
<td>{{ skill.Description }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ path('app_skill_show', {'id': skill.id}) }}" class="btn btn-info btn-sm">👁️ Voir</a>
|
||||
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}" class="btn btn-warning btn-sm">✏️ Modifier</a>
|
||||
<td>
|
||||
<a href="{{ path('app_skill_show', {'id': skill.id}) }}">show</a>
|
||||
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted">Aucune compétence enregistrée.</td>
|
||||
<td colspan="4">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_skill_new') }}" class="btn btn-success mt-3">➕ Ajouter une compétence</a>
|
||||
<a href="{{ path('app_skill_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,13 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Nouvelle compétence{% endblock %}
|
||||
{% block title %}New Skill{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Ajouter une nouvelle compétence</h1>
|
||||
<h1>Create new Skill</h1>
|
||||
|
||||
{{ include('skill/_form.html.twig') }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_skill_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
</div>
|
||||
<a href="{{ path('app_skill_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
@ -1,30 +1,30 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Détail de la compétence{% endblock %}
|
||||
{% block title %}Skill{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🔍 Détail de la compétence</h1>
|
||||
<h1>Skill</h1>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<td>{{ skill.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<td>{{ skill.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ skill.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ skill.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Wording</th>
|
||||
<td>{{ skill.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ skill.Description }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_skill_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}" class="btn btn-warning">✏️ Modifier</a>
|
||||
{{ include('skill/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_skill_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}">edit</a>
|
||||
|
||||
{{ include('skill/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier une pièce{% endblock %}
|
||||
{% block title %}Edit Stock{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier une pièce détachée</h1>
|
||||
<h1>Edit Stock</h1>
|
||||
|
||||
{{ include('stock/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('stock/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_stock_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
{{ include('stock/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_stock_index') }}">back to list</a>
|
||||
|
||||
{{ include('stock/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,19 +1,19 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Liste des pièces détachées{% endblock %}
|
||||
{% block title %}Stock index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">📦 Pièces détachées disponibles</h1>
|
||||
<h1>Stock index</h1>
|
||||
|
||||
<table class="table table-striped table-bordered align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nom</th>
|
||||
<th>Description</th>
|
||||
<th>Quantité</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Wording</th>
|
||||
<th>Description</th>
|
||||
<th>Quantity</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for stock in stocks %}
|
||||
@ -22,18 +22,18 @@
|
||||
<td>{{ stock.Wording }}</td>
|
||||
<td>{{ stock.Description }}</td>
|
||||
<td>{{ stock.Quantity }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ path('app_stock_show', {'id': stock.id}) }}" class="btn btn-info btn-sm">👁️ Voir</a>
|
||||
<a href="{{ path('app_stock_edit', {'id': stock.id}) }}" class="btn btn-warning btn-sm">✏️ Modifier</a>
|
||||
<td>
|
||||
<a href="{{ path('app_stock_show', {'id': stock.id}) }}">show</a>
|
||||
<a href="{{ path('app_stock_edit', {'id': stock.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">Aucune pièce en stock.</td>
|
||||
<td colspan="5">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_stock_new') }}" class="btn btn-success mt-3">➕ Ajouter une pièce</a>
|
||||
<a href="{{ path('app_stock_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,13 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Nouvelle pièce détachée{% endblock %}
|
||||
{% block title %}New Stock{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Ajouter une nouvelle pièce</h1>
|
||||
<h1>Create new Stock</h1>
|
||||
|
||||
{{ include('stock/_form.html.twig') }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_stock_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
</div>
|
||||
<a href="{{ path('app_stock_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
@ -1,34 +1,34 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Détail de la pièce{% endblock %}
|
||||
{% block title %}Stock{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🔍 Détail d'une pièce détachée</h1>
|
||||
<h1>Stock</h1>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<td>{{ stock.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<td>{{ stock.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ stock.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Quantité</th>
|
||||
<td>{{ stock.Quantity }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ stock.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Wording</th>
|
||||
<td>{{ stock.Wording }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ stock.Description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Quantity</th>
|
||||
<td>{{ stock.Quantity }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_stock_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
<a href="{{ path('app_stock_edit', {'id': stock.id}) }}" class="btn btn-warning">✏️ Modifier</a>
|
||||
{{ include('stock/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_stock_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_stock_edit', {'id': stock.id}) }}">edit</a>
|
||||
|
||||
{{ include('stock/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier un utilisateur{% endblock %}
|
||||
{% block title %}Edit User{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier un utilisateur</h1>
|
||||
<h1>Edit User</h1>
|
||||
|
||||
{{ include('user/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('user/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_user_index') }}" class="btn btn-secondary">← Retour à la liste des utilisateurs</a>
|
||||
{{ include('user/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_user_index') }}">back to list</a>
|
||||
|
||||
{{ include('user/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,23 +1,23 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Liste des utilisateurs{% endblock %}
|
||||
{% block title %}User index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Liste des utilisateurs</h1>
|
||||
<h1>User index</h1>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Email</th>
|
||||
<th>Prénom</th>
|
||||
<th>Nom</th>
|
||||
<th>Date de naissance</th>
|
||||
<th>Téléphone</th>
|
||||
<th>Rôles</th>
|
||||
<th>Compétences</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Email</th>
|
||||
<th>FirstName</th>
|
||||
<th>LastName</th>
|
||||
<th>BirthDate</th>
|
||||
<th>Phone</th>
|
||||
<th>Roles</th>
|
||||
<th>Password</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
@ -28,38 +28,20 @@
|
||||
<td>{{ user.LastName }}</td>
|
||||
<td>{{ user.BirthDate ? user.BirthDate|date('Y-m-d') : '' }}</td>
|
||||
<td>{{ user.Phone }}</td>
|
||||
<td>{{ user.roles ? user.roles|json_encode : '' }}</td>
|
||||
<td>{{ user.password }}</td>
|
||||
<td>
|
||||
{% if user.roles %}
|
||||
<ul>
|
||||
{% for role in user.roles %}
|
||||
<li>{{ role }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if user.skills|length > 0 %}
|
||||
<ul>
|
||||
{% for skill in user.skills %}
|
||||
<li>{{ skill.Wording }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
Aucune compétence
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ path('app_user_show', {'id': user.id}) }}" class="btn btn-info btn-sm">Voir</a>
|
||||
<a href="{{ path('app_user_edit', {'id': user.id}) }}" class="btn btn-secondary btn-sm">Modifier</a>
|
||||
<a href="{{ path('app_user_show', {'id': user.id}) }}">show</a>
|
||||
<a href="{{ path('app_user_edit', {'id': user.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="9">Aucun utilisateur trouvé</td>
|
||||
<td colspan="9">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_user_new') }}" class="btn btn-success">Créer un nouvel utilisateur</a>
|
||||
<a href="{{ path('app_user_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,13 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Nouveau utilisateur{% endblock %}
|
||||
{% block title %}New User{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Créer un nouvel utilisateur</h1>
|
||||
<h1>Create new User</h1>
|
||||
|
||||
{{ include('user/_form.html.twig') }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_user_index') }}" class="btn btn-secondary">← Retour à la liste des utilisateurs</a>
|
||||
</div>
|
||||
<a href="{{ path('app_user_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
@ -1,67 +1,50 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Utilisateur{% endblock %}
|
||||
{% block title %}User{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Détails de l'utilisateur</h1>
|
||||
<h1>User</h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ user.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>{{ user.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Prénom</th>
|
||||
<td>{{ user.FirstName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<td>{{ user.LastName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date de naissance</th>
|
||||
<td>{{ user.BirthDate ? user.BirthDate|date('Y-m-d') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Téléphone</th>
|
||||
<td>{{ user.Phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Rôles</th>
|
||||
<td>
|
||||
{% if user.roles %}
|
||||
<ul>
|
||||
{% for role in user.roles %}
|
||||
<li>{{ role }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Compétences</th>
|
||||
<td>
|
||||
{% if user.skills|length > 0 %}
|
||||
<ul>
|
||||
{% for skill in user.skills %}
|
||||
<li>{{ skill.Wording }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
Aucune compétence
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ user.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>{{ user.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>FirstName</th>
|
||||
<td>{{ user.FirstName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>LastName</th>
|
||||
<td>{{ user.LastName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>BirthDate</th>
|
||||
<td>{{ user.BirthDate ? user.BirthDate|date('Y-m-d') : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Phone</th>
|
||||
<td>{{ user.Phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Roles</th>
|
||||
<td>{{ user.roles ? user.roles|json_encode : '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Password</th>
|
||||
<td>{{ user.password }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_user_index') }}" class="btn btn-primary">Retour à la liste</a>
|
||||
<a href="{{ path('app_user_edit', {'id': user.id}) }}" class="btn btn-warning">Modifier</a>
|
||||
<a href="{{ path('app_user_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_user_edit', {'id': user.id}) }}">edit</a>
|
||||
|
||||
{{ include('user/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Modifier un véhicule{% endblock %}
|
||||
{% block title %}Edit Vehicle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">✏️ Modifier un véhicule</h1>
|
||||
<h1>Edit Vehicle</h1>
|
||||
|
||||
{{ include('vehicle/_form.html.twig', {'button_label': 'Mettre à jour'}) }}
|
||||
{{ include('vehicle/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_vehicle_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
{{ include('vehicle/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_vehicle_index') }}">back to list</a>
|
||||
|
||||
{{ include('vehicle/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
@ -1,19 +1,18 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Liste des véhicules{% endblock %}
|
||||
{% block title %}Vehicle index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🚗 Liste des véhicules</h1>
|
||||
<h1>Vehicle index</h1>
|
||||
|
||||
<table class="table table-striped table-bordered align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Immatriculation</th>
|
||||
<th>Marque</th>
|
||||
<th>Modèle</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>LicensePlate</th>
|
||||
<th>Brand</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for vehicle in vehicles %}
|
||||
@ -21,19 +20,18 @@
|
||||
<td>{{ vehicle.id }}</td>
|
||||
<td>{{ vehicle.LicensePlate }}</td>
|
||||
<td>{{ vehicle.Brand }}</td>
|
||||
<td>{{ vehicle.Model }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ path('app_vehicle_show', {'id': vehicle.id}) }}" class="btn btn-info btn-sm">👁️ Voir</a>
|
||||
<a href="{{ path('app_vehicle_edit', {'id': vehicle.id}) }}" class="btn btn-warning btn-sm">✏️ Modifier</a>
|
||||
<td>
|
||||
<a href="{{ path('app_vehicle_show', {'id': vehicle.id}) }}">show</a>
|
||||
<a href="{{ path('app_vehicle_edit', {'id': vehicle.id}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">Aucun véhicule enregistré.</td>
|
||||
<td colspan="4">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_vehicle_new') }}" class="btn btn-success mt-3">➕ Ajouter un véhicule</a>
|
||||
<a href="{{ path('app_vehicle_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
@ -1,13 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Nouveau véhicule{% endblock %}
|
||||
{% block title %}New Vehicle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">➕ Ajouter un nouveau véhicule</h1>
|
||||
<h1>Create new Vehicle</h1>
|
||||
|
||||
{{ include('vehicle/_form.html.twig') }}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_vehicle_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
</div>
|
||||
<a href="{{ path('app_vehicle_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
@ -1,34 +1,30 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Détail du véhicule{% endblock %}
|
||||
{% block title %}Vehicle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="mb-4">🔍 Détail du véhicule</h1>
|
||||
<h1>Vehicle</h1>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<td>{{ vehicle.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Immatriculation</th>
|
||||
<td>{{ vehicle.LicensePlate }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Marque</th>
|
||||
<td>{{ vehicle.Brand }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Modèle</th>
|
||||
<td>{{ vehicle.Model }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ vehicle.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>LicensePlate</th>
|
||||
<td>{{ vehicle.LicensePlate }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Brand</th>
|
||||
<td>{{ vehicle.Brand }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ path('app_vehicle_index') }}" class="btn btn-secondary">← Retour à la liste</a>
|
||||
<a href="{{ path('app_vehicle_edit', {'id': vehicle.id}) }}" class="btn btn-warning">✏️ Modifier</a>
|
||||
{{ include('vehicle/_delete_form.html.twig') }}
|
||||
</div>
|
||||
<a href="{{ path('app_vehicle_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('app_vehicle_edit', {'id': vehicle.id}) }}">edit</a>
|
||||
|
||||
{{ include('vehicle/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user