Compare commits

..

No commits in common. "master" and "esteban" have entirely different histories.

65 changed files with 1640 additions and 2063 deletions

4
.gitignore vendored
View File

@ -20,6 +20,4 @@
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###
.idea
/migrations/
.idea

1091
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -14,27 +14,34 @@ security:
entity:
class: App\Entity\Employee
property: nickname
app_combined_provider:
chain:
providers: [app_intern_provider, app_employee_provider]
# used to reload user from session & other features (e.g. switch_user)
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
intern:
lazy: true
provider: app_combined_provider
provider: app_intern_provider
form_login:
login_path: app_login
check_path: app_login
default_target_path: app_index
enable_csrf: true
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
employee:
lazy: true
provider: app_employee_provider
form_login:
login_path: app_login
check_path: app_login
enable_csrf: true
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
@ -49,9 +56,9 @@ security:
# 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: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/register, roles: PUBLIC_ACCESS }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/register, roles: PUBLIC_ACCESS }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
@ -65,4 +72,4 @@ when@test:
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
memory_cost: 10 # Lowest possible value for argon

View File

@ -0,0 +1,67 @@
<?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 Version20241017134137 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 announcement_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE company_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE userApp_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE announcement (id INT NOT NULL, title VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE company (id INT NOT NULL, name VARCHAR(255) NOT NULL, address VARCHAR(255) NOT NULL, tel VARCHAR(255) NOT NULL, mail VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE employee (id INT NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE intern (id INT NOT NULL, cover_letter TEXT NOT NULL, resume VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE userApp (id INT NOT NULL, nickname VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, tel VARCHAR(255) NOT NULL, address VARCHAR(255) NOT NULL, mail VARCHAR(255) NOT NULL, DISCRIMINATOR VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_NICKNAME ON userApp (nickname)');
$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();');
$this->addSql('ALTER TABLE employee ADD CONSTRAINT FK_5D9F75A1BF396750 FOREIGN KEY (id) REFERENCES userApp (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern ADD CONSTRAINT FK_A5795F36BF396750 FOREIGN KEY (id) REFERENCES userApp (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
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 announcement_id_seq CASCADE');
$this->addSql('DROP SEQUENCE company_id_seq CASCADE');
$this->addSql('DROP SEQUENCE userApp_id_seq CASCADE');
$this->addSql('ALTER TABLE employee DROP CONSTRAINT FK_5D9F75A1BF396750');
$this->addSql('ALTER TABLE intern DROP CONSTRAINT FK_A5795F36BF396750');
$this->addSql('DROP TABLE announcement');
$this->addSql('DROP TABLE company');
$this->addSql('DROP TABLE employee');
$this->addSql('DROP TABLE intern');
$this->addSql('DROP TABLE userApp');
$this->addSql('DROP TABLE messenger_messages');
}
}

View File

@ -0,0 +1,52 @@
<?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 Version20241017142722 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 status_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE status (id INT NOT NULL, label VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('ALTER TABLE announcement ADD company_id INT NOT NULL');
$this->addSql('ALTER TABLE announcement ADD status_id INT NOT NULL');
$this->addSql('ALTER TABLE announcement ADD CONSTRAINT FK_4DB9D91C979B1AD6 FOREIGN KEY (company_id) REFERENCES company (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE announcement ADD CONSTRAINT FK_4DB9D91C6BF700BD FOREIGN KEY (status_id) REFERENCES status (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_4DB9D91C979B1AD6 ON announcement (company_id)');
$this->addSql('CREATE INDEX IDX_4DB9D91C6BF700BD ON announcement (status_id)');
$this->addSql('ALTER TABLE employee ADD company_id INT NOT NULL');
$this->addSql('ALTER TABLE employee ADD CONSTRAINT FK_5D9F75A1979B1AD6 FOREIGN KEY (company_id) REFERENCES company (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_5D9F75A1979B1AD6 ON employee (company_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 announcement DROP CONSTRAINT FK_4DB9D91C6BF700BD');
$this->addSql('DROP SEQUENCE status_id_seq CASCADE');
$this->addSql('DROP TABLE status');
$this->addSql('ALTER TABLE announcement DROP CONSTRAINT FK_4DB9D91C979B1AD6');
$this->addSql('DROP INDEX IDX_4DB9D91C979B1AD6');
$this->addSql('DROP INDEX IDX_4DB9D91C6BF700BD');
$this->addSql('ALTER TABLE announcement DROP company_id');
$this->addSql('ALTER TABLE announcement DROP status_id');
$this->addSql('ALTER TABLE employee DROP CONSTRAINT FK_5D9F75A1979B1AD6');
$this->addSql('DROP INDEX IDX_5D9F75A1979B1AD6');
$this->addSql('ALTER TABLE employee DROP company_id');
}
}

View File

@ -0,0 +1,46 @@
<?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 Version20241017152949 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 favorites (intern_id INT NOT NULL, announcement_id INT NOT NULL, PRIMARY KEY(intern_id, announcement_id))');
$this->addSql('CREATE INDEX IDX_E46960F5525DD4B4 ON favorites (intern_id)');
$this->addSql('CREATE INDEX IDX_E46960F5913AEA17 ON favorites (announcement_id)');
$this->addSql('CREATE TABLE applications (intern_id INT NOT NULL, announcement_id INT NOT NULL, PRIMARY KEY(intern_id, announcement_id))');
$this->addSql('CREATE INDEX IDX_F7C966F0525DD4B4 ON applications (intern_id)');
$this->addSql('CREATE INDEX IDX_F7C966F0913AEA17 ON applications (announcement_id)');
$this->addSql('ALTER TABLE favorites ADD CONSTRAINT FK_E46960F5525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE favorites ADD CONSTRAINT FK_E46960F5913AEA17 FOREIGN KEY (announcement_id) REFERENCES announcement (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE applications ADD CONSTRAINT FK_F7C966F0525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE applications ADD CONSTRAINT FK_F7C966F0913AEA17 FOREIGN KEY (announcement_id) REFERENCES announcement (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
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 favorites DROP CONSTRAINT FK_E46960F5525DD4B4');
$this->addSql('ALTER TABLE favorites DROP CONSTRAINT FK_E46960F5913AEA17');
$this->addSql('ALTER TABLE applications DROP CONSTRAINT FK_F7C966F0525DD4B4');
$this->addSql('ALTER TABLE applications DROP CONSTRAINT FK_F7C966F0913AEA17');
$this->addSql('DROP TABLE favorites');
$this->addSql('DROP TABLE applications');
}
}

View File

@ -0,0 +1,110 @@
<?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 Version20241114132304 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 degree_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE faq_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE intern_application_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE intern_degree_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE intern_favorite_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE intern_skill_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE message_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 TABLE degree (id INT NOT NULL, label VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE faq (id INT NOT NULL, question TEXT NOT NULL, answer TEXT DEFAULT NULL, update_date DATE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE intern_application (id INT NOT NULL, application_id INT DEFAULT NULL, intern_id INT DEFAULT NULL, application_date DATE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_4EDBBCC83E030ACD ON intern_application (application_id)');
$this->addSql('CREATE INDEX IDX_4EDBBCC8525DD4B4 ON intern_application (intern_id)');
$this->addSql('CREATE TABLE intern_degree (id INT NOT NULL, degree_id INT DEFAULT NULL, intern_id INT DEFAULT NULL, graduation_date DATE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_E68CCB23B35C5756 ON intern_degree (degree_id)');
$this->addSql('CREATE INDEX IDX_E68CCB23525DD4B4 ON intern_degree (intern_id)');
$this->addSql('CREATE TABLE intern_favorite (id INT NOT NULL, announcement_id INT DEFAULT NULL, intern_id INT DEFAULT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_A709862E913AEA17 ON intern_favorite (announcement_id)');
$this->addSql('CREATE INDEX IDX_A709862E525DD4B4 ON intern_favorite (intern_id)');
$this->addSql('CREATE TABLE intern_skill (id INT NOT NULL, skill_id INT DEFAULT NULL, intern_id INT DEFAULT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_75E1C4DC5585C142 ON intern_skill (skill_id)');
$this->addSql('CREATE INDEX IDX_75E1C4DC525DD4B4 ON intern_skill (intern_id)');
$this->addSql('CREATE TABLE message (id INT NOT NULL, sender_id INT DEFAULT NULL, receiver_id INT DEFAULT NULL, content TEXT NOT NULL, sending_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_B6BD307FF624B39D ON message (sender_id)');
$this->addSql('CREATE INDEX IDX_B6BD307FCD53EDB6 ON message (receiver_id)');
$this->addSql('CREATE TABLE skill (id INT NOT NULL, label VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('ALTER TABLE intern_application ADD CONSTRAINT FK_4EDBBCC83E030ACD FOREIGN KEY (application_id) REFERENCES announcement (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_application ADD CONSTRAINT FK_4EDBBCC8525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_degree ADD CONSTRAINT FK_E68CCB23B35C5756 FOREIGN KEY (degree_id) REFERENCES degree (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_degree ADD CONSTRAINT FK_E68CCB23525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_favorite ADD CONSTRAINT FK_A709862E913AEA17 FOREIGN KEY (announcement_id) REFERENCES announcement (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_favorite ADD CONSTRAINT FK_A709862E525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_skill ADD CONSTRAINT FK_75E1C4DC5585C142 FOREIGN KEY (skill_id) REFERENCES skill (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_skill ADD CONSTRAINT FK_75E1C4DC525DD4B4 FOREIGN KEY (intern_id) REFERENCES intern (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE message ADD CONSTRAINT FK_B6BD307FF624B39D FOREIGN KEY (sender_id) REFERENCES userApp (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE message ADD CONSTRAINT FK_B6BD307FCD53EDB6 FOREIGN KEY (receiver_id) REFERENCES userApp (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE favorites DROP CONSTRAINT fk_e46960f5525dd4b4');
$this->addSql('ALTER TABLE favorites DROP CONSTRAINT fk_e46960f5913aea17');
$this->addSql('ALTER TABLE applications DROP CONSTRAINT fk_f7c966f0525dd4b4');
$this->addSql('ALTER TABLE applications DROP CONSTRAINT fk_f7c966f0913aea17');
$this->addSql('DROP TABLE favorites');
$this->addSql('DROP TABLE applications');
$this->addSql('ALTER TABLE announcement ADD creation_date DATE NOT NULL');
}
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 degree_id_seq CASCADE');
$this->addSql('DROP SEQUENCE faq_id_seq CASCADE');
$this->addSql('DROP SEQUENCE intern_application_id_seq CASCADE');
$this->addSql('DROP SEQUENCE intern_degree_id_seq CASCADE');
$this->addSql('DROP SEQUENCE intern_favorite_id_seq CASCADE');
$this->addSql('DROP SEQUENCE intern_skill_id_seq CASCADE');
$this->addSql('DROP SEQUENCE message_id_seq CASCADE');
$this->addSql('DROP SEQUENCE skill_id_seq CASCADE');
$this->addSql('CREATE TABLE favorites (intern_id INT NOT NULL, announcement_id INT NOT NULL, PRIMARY KEY(intern_id, announcement_id))');
$this->addSql('CREATE INDEX idx_e46960f5913aea17 ON favorites (announcement_id)');
$this->addSql('CREATE INDEX idx_e46960f5525dd4b4 ON favorites (intern_id)');
$this->addSql('CREATE TABLE applications (intern_id INT NOT NULL, announcement_id INT NOT NULL, PRIMARY KEY(intern_id, announcement_id))');
$this->addSql('CREATE INDEX idx_f7c966f0913aea17 ON applications (announcement_id)');
$this->addSql('CREATE INDEX idx_f7c966f0525dd4b4 ON applications (intern_id)');
$this->addSql('ALTER TABLE favorites ADD CONSTRAINT fk_e46960f5525dd4b4 FOREIGN KEY (intern_id) REFERENCES intern (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE favorites ADD CONSTRAINT fk_e46960f5913aea17 FOREIGN KEY (announcement_id) REFERENCES announcement (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE applications ADD CONSTRAINT fk_f7c966f0525dd4b4 FOREIGN KEY (intern_id) REFERENCES intern (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE applications ADD CONSTRAINT fk_f7c966f0913aea17 FOREIGN KEY (announcement_id) REFERENCES announcement (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE intern_application DROP CONSTRAINT FK_4EDBBCC83E030ACD');
$this->addSql('ALTER TABLE intern_application DROP CONSTRAINT FK_4EDBBCC8525DD4B4');
$this->addSql('ALTER TABLE intern_degree DROP CONSTRAINT FK_E68CCB23B35C5756');
$this->addSql('ALTER TABLE intern_degree DROP CONSTRAINT FK_E68CCB23525DD4B4');
$this->addSql('ALTER TABLE intern_favorite DROP CONSTRAINT FK_A709862E913AEA17');
$this->addSql('ALTER TABLE intern_favorite DROP CONSTRAINT FK_A709862E525DD4B4');
$this->addSql('ALTER TABLE intern_skill DROP CONSTRAINT FK_75E1C4DC5585C142');
$this->addSql('ALTER TABLE intern_skill DROP CONSTRAINT FK_75E1C4DC525DD4B4');
$this->addSql('ALTER TABLE message DROP CONSTRAINT FK_B6BD307FF624B39D');
$this->addSql('ALTER TABLE message DROP CONSTRAINT FK_B6BD307FCD53EDB6');
$this->addSql('DROP TABLE degree');
$this->addSql('DROP TABLE faq');
$this->addSql('DROP TABLE intern_application');
$this->addSql('DROP TABLE intern_degree');
$this->addSql('DROP TABLE intern_favorite');
$this->addSql('DROP TABLE intern_skill');
$this->addSql('DROP TABLE message');
$this->addSql('DROP TABLE skill');
$this->addSql('ALTER TABLE announcement DROP creation_date');
}
}

View File

@ -0,0 +1,32 @@
<?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 Version20241121135116 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('ALTER TABLE userapp ALTER roles DROP NOT NULL');
}
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 userApp ALTER roles SET NOT NULL');
}
}

View File

@ -0,0 +1,38 @@
<?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 Version20241121140219 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('ALTER TABLE announcement DROP CONSTRAINT fk_4db9d91c6bf700bd');
$this->addSql('DROP INDEX idx_4db9d91c6bf700bd');
$this->addSql('ALTER TABLE announcement ADD status VARCHAR(255) NOT NULL');
$this->addSql('ALTER TABLE announcement DROP status_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 announcement ADD status_id INT NOT NULL');
$this->addSql('ALTER TABLE announcement DROP status');
$this->addSql('ALTER TABLE announcement ADD CONSTRAINT fk_4db9d91c6bf700bd FOREIGN KEY (status_id) REFERENCES status (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX idx_4db9d91c6bf700bd ON announcement (status_id)');
}
}

View File

@ -0,0 +1,31 @@
<?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 Version20241121153037 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
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
}
}

View File

@ -3,6 +3,7 @@
namespace App\Controller;
use App\Entity\Announcement;
use App\Entity\InternApplication;
use App\Form\AnnouncementType;
use App\Repository\AnnouncementRepository;
use Doctrine\ORM\EntityManagerInterface;
@ -10,118 +11,117 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[Route('/announcement')]
final class AnnouncementController extends AbstractController
#[Route('/announcement', name: 'app_announcement')]
class AnnouncementController extends AbstractController
{
#[Route('/', name: 'app_announcement_index')]
public function list(Request $request, AnnouncementRepository $announcementRepository): Response
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly AnnouncementRepository $announcementRepository
)
{
$user = $this->getUser();
$announcements = [];
if (in_array('ROLE_ADMIN', $user->getRoles())) {
$showNonValidated = $request->query->get('show_non_validated');
if ($showNonValidated) {
$announcements = $announcementRepository->findBy(['status' => 'notVerified']);
}
if (!$showNonValidated){
$announcements = $announcementRepository->findAll();
}
}
if (in_array('ROLE_EMPLOYEE', $user->getRoles())) {
$company = $user->getCompany();
if ($company)
{
$announcements = $announcementRepository->findBy(['company' => $company]);
}
}
if (in_array('ROLE_INTERN', $user->getRoles()))
{
$announcements = $announcementRepository->findBy(['status' => 'Verified']);
}
return $this->render('announcement/index.html.twig', [
'announcements' => $announcements,
'showNonValidated' => $request->query->get('show_non_validated', false),
]);
}
#[Route('/new', name: 'app_announcement_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
#[Route('/add', name: '_add')]
#[IsGranted('ROLE_ADMIN')]
public function addAnnouncement(Request $request): Response
{
$announcement = new Announcement();
$form = $this->createForm(AnnouncementType::class, $announcement);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if($form->isSubmitted() && $form->isValid())
{
//met la date de création de l'annonce au moment où le formulaire est envoyé
$announcement->setCreationDate(new \DateTime());
$announcement->setStatus('notVerified');
$entityManager->persist($announcement);
$entityManager->flush();
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
$this->entityManager->persist($announcement);
$this->entityManager->flush();
$this->addFlash('success', 'Annonce créée avec succès.');
return $this->redirectToRoute('app_announcement_list');
}
return $this->render('announcement/new.html.twig', [
'announcement' => $announcement,
'form' => $form,
return $this->render('announcement/add.html.twig', [
'announcementForm' => $form,
]);
}
#[Route('/{id}', name: 'app_announcement_show', methods: ['GET'])]
public function show(Announcement $announcement): Response
#[Route('/list', name: '_list')]
public function list(): Response
{
return $this->render('announcement/show.html.twig', [
'announcement' => $announcement,
$announcements = $this->announcementRepository->findAll();
return $this->render('announcement/list.html.twig', [
'announcements' => $announcements,
]);
}
#[Route('/{id}/edit', name: 'app_announcement_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
#[Route('/update/{id}', name: '_update')]
#[IsGranted('ROLE_ADMIN')]
public function update(int $id, Request $request): Response
{
$announcement = $this->announcementRepository->find($id);
$form = $this->createForm(AnnouncementType::class, $announcement);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
if($form->isSubmitted() && $form->isValid())
{
$this->entityManager->persist($announcement);
$this->entityManager->flush();
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
$this->addFlash('success', 'Annonce modifiéé avec succès.');
return $this->redirectToRoute('app_announcement_list');
}
return $this->render('announcement/edit.html.twig', [
'announcement' => $announcement,
'form' => $form,
return $this->render('announcement/add.html.twig', [
'formAdd' => $form,
]);
}
#[Route('/{id}', name: 'app_announcement_delete', methods: ['POST'])]
public function delete(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
#[Route('/delete/{id}', name: '_delete')]
#[IsGranted('ROLE_ADMIN')]
public function delete(int $id): Response
{
if ($this->isCsrfTokenValid('delete'.$announcement->getId(), $request->getPayload()->getString('_token'))) {
$entityManager->remove($announcement);
$entityManager->flush();
}
$announcement = $this->announcementRepository->find($id);
$this->entityManager->remove($announcement);
$this->entityManager->flush();
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
return $this->redirectToRoute('app_announcement_list');
}
#[Route('/{id}/validate', name: 'app_announcement_validate', methods: ['POST'])]
public function validate(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
#[Route('/apply/{id}', name: '_apply')]
public function applyToAnnouncement(int $id): Response
{
if ($announcement->getStatus() !== 'Verified')
{
$announcement->setStatus('Verified');
$entityManager->flush();
$announcement = $this->announcementRepository->find($id);
$user = $this->getUser();
$existingCandidature = $this->entityManager->getRepository(InternApplication::class)->findOneBy([
'intern' => $user,
'announcement' => $announcement
]);
if($existingCandidature) {
$this->addFlash('error', 'Vous avez déjà postulé à cette annonce.');
return $this->redirectToRoute('app_announcement_list');
}
return $this->redirectToRoute('app_announcement_show',
['id' => $announcement->getId()], Response::HTTP_SEE_OTHER);
$application = new InternApplication();
$application->setIntern($user);
$application->setIntern($announcement);
$application->setApplicationDate(new \DateTime());
$this->entityManager->persist($application);
$this->entityManager->flush();
$this->addFlash('success', 'Votre candidature a été envoyée avec succès.');
return $this->redirectToRoute('annonce_list', ['id' => $announcement->getId()]);
}
#[Route('/filterByCompany', name: '_filterByCompany')]
public function filterByCompany(int $id): Response
{
return $this->redirectToRoute('annonce_list', ['id' => $id]);
}
}

View File

@ -22,6 +22,26 @@ final class EmployeeController extends AbstractController
]);
}
#[Route('/new', name: 'app_employee_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
{
$employee = new Employee();
$form = $this->createForm(EmployeeType::class, $employee);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($employee);
$entityManager->flush();
return $this->redirectToRoute('app_employee_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('employee/new.html.twig', [
'employee' => $employee,
'form' => $form,
]);
}
#[Route('/{id}', name: 'app_employee_show', methods: ['GET'])]
public function show(Employee $employee): Response
{

View File

@ -32,7 +32,6 @@ final class FAQController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$fAQ->setUpdateDate(new \DateTime());
$entityManager->persist($fAQ);
$entityManager->flush();
@ -61,7 +60,6 @@ final class FAQController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$fAQ->setUpdateDate(new \DateTime());
$entityManager->flush();
return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER);
@ -84,4 +82,4 @@ final class FAQController extends AbstractController
return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER);
}
}
}

View File

@ -19,7 +19,7 @@ class IndexController extends AbstractController
{
}
#[Route('/', name: 'app_index')]
#[Route('/index', name: 'app_index')]
public function index(): Response
{
$companies = $this->companyRepository->findAll();
@ -43,7 +43,6 @@ class IndexController extends AbstractController
}
return $this->render('index/index.html.twig', [
'companies' => $companiescoord,
'id' => $this->getUser()->getId(),
]);
}

View File

@ -22,6 +22,26 @@ final class InternController extends AbstractController
]);
}
#[Route('/new', name: 'app_intern_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
{
$intern = new Intern();
$form = $this->createForm(InternType::class, $intern);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($intern);
$entityManager->flush();
return $this->redirectToRoute('app_intern_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('intern/new.html.twig', [
'intern' => $intern,
'form' => $form,
]);
}
#[Route('/{id}', name: 'app_intern_show', methods: ['GET'])]
public function show(Intern $intern): Response
{

View File

@ -3,10 +3,8 @@
namespace App\Controller;
use App\Entity\Message;
use App\Entity\UserApp;
use App\Form\MessageType;
use App\Repository\MessageRepository;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@ -19,56 +17,27 @@ final class MessageController extends AbstractController
#[Route(name: 'app_message_index', methods: ['GET'])]
public function index(MessageRepository $messageRepository): Response
{
$user = $this->getUser();
$messages = $messageRepository->findByUser($user);
return $this->render('message/index.html.twig', [
'messages' => $messages,
'messages' => $messageRepository->findAll(),
]);
}
#[Route('/conversation/{id}', name: 'app_message_conversation', methods: ['GET'])]
public function conversation(Message $message, MessageRepository $messageRepository): Response
{
$user = $this->getUser();
$otherUser = $message->getSender() === $user ? $message->getReceiver() : $message->getSender();
$conversation = $messageRepository->findByConversation($user, $otherUser);
return $this->render('message/conversation.html.twig', [
'conversation' => $conversation,
'receiverId' => $otherUser->getId(),
'receiver' => $otherUser,
]);
}
#[Route('/new/{receiverId}', name: 'app_message_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager, ?int $receiverId = null, UserRepository $userRepository): Response
#[Route('/new', name: 'app_message_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
{
$message = new Message();
if ($receiverId) {
$receiver = $userRepository->find($receiverId);
if ($receiver) {
$message->setReceiver($receiver);
}
}
$form = $this->createForm(MessageType::class, $message);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$message->setSendingDate(new \DateTime());
$message->setSender($this->getUser());
$entityManager->persist($message);
$entityManager->flush();
return $this->redirectToRoute('app_message_index');
return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('message/new.html.twig', [
'message' => $message,
'form' => $form,
]);
}
@ -88,7 +57,6 @@ final class MessageController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$message->setSendingDate(new \DateTime());
$entityManager->flush();
return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER);
@ -110,6 +78,4 @@ final class MessageController extends AbstractController
return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER);
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\UserApp;
use App\Form\UserAppType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ProfileController extends AbstractController
{
#[Route('/profile', name: 'app_profile')]
public function profile(): Response
{
// Charger l'utilisateur connecté
$user = $this->getUser();
// Vérifiez les rôles si nécessaire
if (!$user) {
throw $this->createAccessDeniedException('Vous devez être connecté pour accéder à cette page.');
}
return $this->render('profile/index.html.twig', [
'user' => $user,
]);
}
#[Route('profile/{id}/edit', name: 'app_profile_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(UserAppType::class, $userApp);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('app_profile', [], Response::HTTP_SEE_OTHER);
}
return $this->render('profile/edit.html.twig', [
'user_app' => $userApp,
'form' => $form,
]);
}
}

View File

@ -37,7 +37,7 @@ class RegistrationController extends AbstractController
// do anything else you need here, like send an email
return $security->login($user, 'form_login', 'main');
return $security->login($user, 'form_login', 'intern');
}
return $this->render('registration/register.html.twig', [
@ -65,7 +65,7 @@ class RegistrationController extends AbstractController
// do anything else you need here, like send an email
return $security->login($user, 'form_login', 'main');
return $security->login($user, 'form_login', 'employee');
}
return $this->render('registration/register.html.twig', [

View File

@ -14,7 +14,7 @@ use Symfony\Component\Routing\Attribute\Route;
#[Route('/user')]
final class UserAppController extends AbstractController
{
#[Route(name: 'app_user_index', methods: ['GET'])]
#[Route(name: 'app_user_app_index', methods: ['GET'])]
public function index(UserRepository $userRepository): Response
{
return $this->render('user_app/index.html.twig', [
@ -22,7 +22,27 @@ final class UserAppController extends AbstractController
]);
}
#[Route('/{id}', name: 'app_user_show', methods: ['GET'])]
// #[Route('/new', name: 'app_user_app_new', methods: ['GET', 'POST'])]
// public function new(Request $request, EntityManagerInterface $entityManager): Response
// {
// $userApp = new UserApp();
// $form = $this->createForm(UserAppType::class, $userApp);
// $form->handleRequest($request);
//
// if ($form->isSubmitted() && $form->isValid()) {
// $entityManager->persist($userApp);
// $entityManager->flush();
//
// return $this->redirectToRoute('app_user_app_index', [], Response::HTTP_SEE_OTHER);
// }
//
// return $this->render('user_app/new.html.twig', [
// 'user_app' => $userApp,
// 'form' => $form,
// ]);
// }
#[Route('/{id}', name: 'app_user_app_show', methods: ['GET'])]
public function show(UserApp $userApp): Response
{
return $this->render('user_app/show.html.twig', [
@ -30,7 +50,7 @@ final class UserAppController extends AbstractController
]);
}
#[Route('/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])]
#[Route('/{id}/edit', name: 'app_user_app_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(UserAppType::class, $userApp);
@ -39,7 +59,7 @@ final class UserAppController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
return $this->redirectToRoute('app_user_app_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('user_app/edit.html.twig', [
@ -48,7 +68,7 @@ final class UserAppController extends AbstractController
]);
}
#[Route('/{id}', name: 'app_user_delete', methods: ['POST'])]
#[Route('/{id}', name: 'app_user_app_delete', methods: ['POST'])]
public function delete(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{
if ($this->isCsrfTokenValid('delete'.$userApp->getId(), $request->getPayload()->getString('_token'))) {
@ -56,6 +76,6 @@ final class UserAppController extends AbstractController
$entityManager->flush();
}
return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
return $this->redirectToRoute('app_user_app_index', [], Response::HTTP_SEE_OTHER);
}
}
}

View File

@ -22,18 +22,15 @@ class Announcement
#[ORM\Column(length: 255)]
private ?string $description = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $creationDate = null;
#[ORM\ManyToOne(inversedBy: 'announcements')]
#[ORM\JoinColumn(nullable: false)]
private ?Company $company = null;
#[ORM\Column(nullable: false)]
private ?string $status = "notVerfied";
#[ORM\Column(nullable: false)]
private ?string $date = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $creationDate = null;
#[ORM\Column(length: 255,nullable: false)]
private ?string $status = "notVerified";
/**
* @var ?Collection<int, InternApplication>
@ -99,7 +96,7 @@ class Announcement
return $this->status;
}
public function setStatus(?string $status): self
public function setStatus(?string $status): static
{
$this->status = $status;
@ -177,16 +174,4 @@ class Announcement
return $this;
}
public function getDate(): ?string
{
return $this->date;
}
public function setDate(string $date): self
{
$this->date = $date;
return $this;
}
}
}

View File

@ -186,6 +186,18 @@ class UserApp implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setVerified(bool $isVerified): static
{
$this->isVerified = $isVerified;
return $this;
}
}

View File

@ -10,7 +10,7 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class AnnouncementType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
@ -20,12 +20,9 @@ class AnnouncementType extends AbstractType
->add('description')
->add('company', EntityType::class, [
'class' => Company::class,
'choice_label' => 'name',
])
->add('date', TextType::class, [
'label' => 'Date de stage',
'required' => true,
'choice_label' => 'id',
])
->add('submit', SubmitType::class)
;
}
@ -35,4 +32,4 @@ class AnnouncementType extends AbstractType
'data_class' => Announcement::class,
]);
}
}
}

View File

@ -13,7 +13,11 @@ class FAQType extends AbstractType
{
$builder
->add('question')
->add('answer');
->add('answer')
->add('updateDate', null, [
'widget' => 'single_text',
])
;
}
public function configureOptions(OptionsResolver $resolver): void

View File

@ -15,10 +15,16 @@ class MessageType extends AbstractType
{
$builder
->add('content')
->add('sendingDate', null, [
'widget' => 'single_text',
])
->add('sender', EntityType::class, [
'class' => UserApp::class,
'choice_label' => 'id',
])
->add('receiver', EntityType::class, [
'class' => UserApp::class,
'choice_label' => 'nickname',
'choice_label' => 'id',
])
;
}

View File

@ -45,7 +45,14 @@ class RegistrationFormType extends AbstractType
new NotBlank(),
]
])
//
// ->add('agreeTerms', CheckboxType::class, [
// 'mapped' => false,
// 'constraints' => [
// new IsTrue([
// 'message' => 'Vous devez accepter les conditions d\'utilisation.',
// ]),
// ],
// ])
->add('plainPassword', PasswordType::class, [
// instead of being set onto the object directly,
// this is read and encoded in the controller

View File

@ -13,6 +13,7 @@ class UserAppType extends AbstractType
{
$builder
->add('nickname')
->add('roles')
->add('password')
->add('firstName')
->add('lastName')

View File

@ -3,7 +3,6 @@
namespace App\Repository;
use App\Entity\Message;
use App\Entity\UserApp;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@ -17,24 +16,28 @@ class MessageRepository extends ServiceEntityRepository
parent::__construct($registry, Message::class);
}
public function findByUser(UserApp $user): array
{
return $this->createQueryBuilder('m')
->where('m.sender = :user OR m.receiver = :user')
->setParameter('user', $user)
->orderBy('m.sendingDate', 'ASC')
->getQuery()
->getResult();
}
// /**
// * @return Message[] Returns an array of Message objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('m.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
public function findByConversation(UserApp $user1, UserApp $user2): array
{
return $this->createQueryBuilder('m')
->where('(m.sender = :user1 AND m.receiver = :user2) OR (m.sender = :user2 AND m.receiver = :user1)')
->setParameter('user1', $user1)
->setParameter('user2', $user2)
->orderBy('m.sendingDate', 'ASC')
->getQuery()
->getResult();
}
// public function findOneBySomeField($value): ?Message
// {
// return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -1,4 +0,0 @@
<form method="post" action="{{ path('app_announcement_delete', {'id': announcement.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ announcement.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -1,4 +0,0 @@
{{ form_start(form) }}
{{ form_widget(form) }}
<button class="btn">{{ button_label|default('Save') }}</button>
{{ form_end(form) }}

View File

@ -0,0 +1,4 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form(announcementForm) }}
{% endblock %}

View File

@ -1,63 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier l'Annonce{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold text-center mb-6">Modifier l'Annonce</h1>
<div class="max-w-4xl mx-auto bg-white p-6 rounded-lg shadow-lg">
<form method="post" action="{{ path('app_announcement_edit', { id: announcement.id }) }}" class="space-y-6">
{{ form_start(form) }}
<div class="mb-4">
<!-- Nom de l'entreprise -->
<label for="announcement_company" class="block text-gray-700 font-semibold">Entreprise</label>
<div>
{{ form_widget(form.company, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
</div>
</div>
<!-- Titre de l'annonce -->
<div class="mb-4">
<label for="announcement_title" class="block text-gray-700 font-semibold">Titre de l'annonce</label>
<div>
{{ form_widget(form.title, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
</div>
</div>
<!-- Description -->
<div>
<label for="announcement_description" class="block text-gray-700 font-semibold">Description</label>
<div>
{{ form_widget(form.description, { 'attr': { 'class': 'w-full p-3 border rounded-md' } }) }}
</div>
</div>
<!-- Date du stage -->
<div>
<label for="announcement_date" class="block text-gray-700 font-semibold">Date du stage</label>
<div>
{{ form_widget(form.date, { 'attr': { 'class': 'w-full p-3 border rounded-md' } }) }}
</div>
</div>
<!-- Submit Button -->
<div class="text-center">
<button type="submit" class="bg-teal-500 text-white px-6 py-3 rounded-md hover:bg-teal-600">
Enregistrer les modifications
</button>
</div>
{{ form_end(form) }}
</form>
</div>
<!-- Bouton Retour -->
<div class="mt-4">
<a href="{{ path('app_announcement_index') }}" class="text-teal-500 flex items-center">
<i class="fas fa-arrow-left mr-2"></i>Retour à la liste des annonces
</a>
</div>
</div>
{% endblock %}

View File

@ -1,82 +1,20 @@
{% extends 'base.html.twig' %}
{% block title %}Liste des Annonces{% endblock %}
{% block title %}Hello AnnouncementController!{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6 text-center">Liste des Annonces</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>
{% if 'ROLE_ADMIN' in app.user.roles %}
<!-- Formulaire pour afficher uniquement les annonces non validées -->
<form method="get" class="mb-6 text-center">
<label class="flex items-center justify-center space-x-2">
<input
type="checkbox"
name="show_non_validated"
value="1"
{% if showNonValidated %}checked{% endif %}
class="rounded text-teal-500"
>
<span class="text-gray-700">Afficher uniquement les annonces non validées</span>
</label>
<button type="submit" class="ml-4 bg-teal-500 text-white px-4 py-2 rounded mt-2">
Appliquer
</button>
</form>
{% endif %}
<div class="example-wrapper">
<h1>Hello {{ controller_name }}! ✅</h1>
{% if 'ROLE_EMPLOYEE' in app.user.roles %}
<!-- Bouton pour créer une annonce -->
<div class="text-center mb-6">
<a href="{{ path('app_announcement_new') }}" class="bg-teal-500 text-white px-6 py-3 rounded-md hover:bg-teal-600">
Créer une annonce
</a>
</div>
{% endif %}
<!-- Liste des annonces -->
<div class="max-w-4xl mx-auto">
{% for announcement in announcements %}
<div class="bg-white p-6 rounded-lg shadow mb-4 relative">
<!-- Statut en haut à droite -->
<div class="absolute top-4 right-4">
{% if announcement.status == 'notVerified' %}
<span class="text-red-500 font-semibold">Non validée</span>
{% else %}
<span class="text-green-500 font-semibold">Validée</span>
{% endif %}
</div>
<!-- Titre de l'annonce -->
<h2 class="text-3xl font-semibold mb-2">{{ announcement.title }}</h2>
<!-- Nom de l'entreprise -->
<p class="text-gray-600 mb-2">{{ announcement.company.name }}</p>
<div class="text-gray-500 text-sm mb-4">
<!-- Date du stage -->
<div class="mb-2">
<i class="fas fa-calendar-alt mr-1"></i>
<span>Date du stage : {{ announcement.date }}</span>
</div>
<!-- Adresse de l'entreprise -->
<div>
<i class="fas fa-map-marker-alt mr-1"></i>
<span>{{ announcement.company.address }}</span>
</div>
</div>
<!-- Lien vers la page de détails -->
<a href="{{ path('app_announcement_show', { id: announcement.id }) }}"
class="bg-teal-500 text-white px-4 py-2 rounded">
Détails
</a>
</div>
{% else %}
<p class="text-center text-gray-500">Aucune annonce disponible.</p>
{% endfor %}
</div>
</div>
This friendly message is coming from:
<ul>
<li>Your controller at <code>C:/Users/csese/Romain/Phpstorm_projets/ProjetHegreSphere/hegresphere/src/Controller/AnnouncementController.php</code></li>
<li>Your template at <code>C:/Users/csese/Romain/Phpstorm_projets/ProjetHegreSphere/hegresphere/templates/announcement/index.html.twig</code></li>
</ul>
</div>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends 'base.html.twig' %}
{% block title %}Bienvenue sur Hegreshpere{% endblock %}
{% block body %}
<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>
<h1> Liste des annonces</h1>
{% for ann in announcements %}
<h2> {{ ann.title }} </h2>
<h3> {{ ann.company.name }} </h3>
<p> {{ ann.description }} </p>
------------------------------
<p> {{ ann.creationDate|format("d-m-y") }} </p>
{% endfor %}
{% endblock %}

View File

@ -1,31 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Créer une Annonce{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Créer une Annonce</h1>
{{ form_start(form) }}
<div class="mb-4">
{{ form_label(form.title) }}
{{ form_widget(form.title, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }}
</div>
<div class="mb-4">
{{ form_label(form.description) }}
{{ form_widget(form.description, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }}
</div>
<div class="mb-4">
{{ form_label(form.date) }}
{{ form_widget(form.date, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }}
</div>
<div class="mb-4">
{{ form_label(form.company) }}
{{ form_widget(form.company, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }}
</div>
<button type="submit" class="bg-teal-500 text-white px-4 py-2 rounded">
Créer l'annonce
</button>
{{ form_end(form) }}
</div>
{% endblock %}

View File

@ -1,81 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Détails de l'Annonce{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6">Détails de l'Annonce</h1>
<!-- Détails de l'annonce -->
<div class="bg-white p-6 rounded-lg shadow mb-4">
<!-- Titre de l'annonce -->
<h2 class="text-3xl font-semibold mb-2">{{ announcement.title }}</h2>
<!-- Nom de l'entreprise -->
<p class="text-gray-600 mb-2">{{ announcement.company.name }}</p>
<div class="text-gray-500 text-sm mb-4">
<!-- Date du stage -->
<div class="mb-2">
<i class="fas fa-calendar-alt mr-1"></i>
<span>Date du stage : {{ announcement.date }}</span>
</div>
<!-- Adresse de l'entreprise -->
<div>
<i class="fas fa-map-marker-alt mr-1"></i>
<span>{{ announcement.company.address }}</span>
</div>
</div>
<!-- Description du stage -->
<div class="mb-4">
<strong>Description du stage : </strong>
<p>{{ announcement.description }}</p>
</div>
<!-- Statut de l'annonce -->
<div class="mb-4">
<strong>Statut : </strong>
<span class="text-sm {% if announcement.status == 'notVerified' %}text-red-500{% else %}text-green-500{% endif %}">
{% if announcement.status == 'notVerified' %}
Non validée
{% else %}
Validée
{% endif %}
</span>
</div>
<!-- Date de création -->
<div class="mb-4">
<strong>Date de création : </strong>
<span>{{ announcement.creationDate | date('d/m/Y') }}</span>
</div>
{% if 'ROLE_ADMIN' in app.user.roles %}
<!-- Boutons Modifier et Valider -->
<div class="mt-4 flex space-x-4">
<a href="{{ path('app_announcement_edit', { id: announcement.id }) }}"
class="bg-teal-500 text-white px-4 py-2 rounded hover:bg-teal-600">
Modifier l'annonce
</a>
{% if announcement.status == 'notVerified' %}
<form method="post" action="{{ path('app_announcement_validate', { id: announcement.id }) }}">
<button type="submit" class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">
Valider l'annonce
</button>
</form>
{% endif %}
</div>
{% endif %}
</div>
<!-- Bouton de retour à la liste -->
<a href="{{ path('app_announcement_index') }}" class="text-teal-500 flex items-center mb-4">
<i class="fas fa-arrow-left mr-2"></i>Retour à la liste des annonces
</a>
</div>
{% endblock %}

View File

@ -5,6 +5,8 @@
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>{% block title %}Hegreshere{% endblock %}</title>
{# Tailwind CSS CDN #}
<script src="https://cdn.tailwindcss.com"></script>
@ -18,58 +20,33 @@
}
</style>
</head>
<body class="bg-gray-100 flex flex-col min-h-screen">
<body class="bg-gray-100">
<header class="bg-gray-900 text-white">
<div class="container mx-auto flex justify-between items-center py-4 px-6">
<div class="flex items-center">
<i class="fas fa-briefcase text-2xl mr-2"></i>
<span class="text-xl font-bold">HegreSphere</span>
</div>
<nav class="space-x-20">
<nav class="space-x-6">
<a class="hover:text-teal-400" href="{{ path('app_index') }}">Accueil</a>
<a class="hover:text-teal-400" href="{{ path('app_announcement_index') }}">Stages</a>
<a class="hover:text-teal-400" href="{{ path('app_faq_index') }}">FAQ</a>
<a class="hover:text-teal-400" href="{{ path('app_message_index') }}">Messagerie</a>
<a class="hover:text-teal-400" href="{{ path('app_index') }}">Stages</a>
<a class="hover:text-teal-400" href="{{ path('app_index') }}">À propos de nous</a>
<a class="hover:text-teal-400" href="{{ path('app_index') }}">Nous contacter</a>
</nav>
<div class="flex space-x-4">
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full" href="{{ path('app_profile') }}">
{% if app.user %}
<div>
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full" href="{{ path('app_user_app_show', { id: app.user.id }) }}">
Profil
</a>
<a class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded-full" href="{{ path('app_logout') }}">
Déconnexion
</a>
</div>
{% endif %}
</div>
</header>
<main class="flex-grow">
{# Block for the specific page content #}
<main>
{% block body %}
{% endblock %}
</main>
<footer class="bg-gray-800 text-gray-400">
<div class="container mx-auto py-6 px-6 grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Company Info -->
<div>
<h3 class="text-white text-lg font-bold mb-4">À propos de nous</h3>
<p>HegreSphere est une plateforme dédiée aux opportunités de stages et au soutien des étudiants dans leur parcours professionnel.</p>
</div>
<!-- Quick Links -->
<div>
<h3 class="text-white text-lg font-bold mb-4">Liens utiles</h3>
<ul class="space-y-2">
<li><a href="{{ path('app_index') }}" class="hover:text-teal-400">Accueil</a></li>
<li><a href="{{ path('app_announcement_index') }}" class="hover:text-teal-400">Liste des stages</a></li>
</ul>
</div>
<div>
<h3 class="text-white text-lg font-bold mb-4">Contactez-nous</h3>
<p>Email: support@hegresphere.com</p>
<p>Téléphone: +33 1 23 45 67 89</p>
</div>
</div>
</footer>
</body>
</html>

View File

@ -1,55 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier l'entreprise{% endblock %}
{% block title %}Edit Company{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Modifier l'entreprise</h1>
<h1>Edit Company</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('company/_form.html.twig', {'button_label': 'Update'}) }}
<div class="mb-4">
<label for="company_name" class="block text-lg font-medium text-gray-700 mb-2">Nom de l'entreprise</label>
<div class="mt-1">
{{ form_widget(form.name, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<a href="{{ path('app_company_index') }}">back to list</a>
<div class="mb-4">
<label for="company_address" class="block text-lg font-medium text-gray-700 mb-2">Adresse</label>
<div class="mt-1">
{{ form_widget(form.address, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mb-4">
<label for="company_tel" class="block text-lg font-medium text-gray-700 mb-2">Téléphone</label>
<div class="mt-1">
{{ form_widget(form.tel, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mb-4">
<label for="company_mail" class="block text-lg font-medium text-gray-700 mb-2">Email</label>
<div class="mt-1">
{{ form_widget(form.mail, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Mettre à jour l'entreprise
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_company_index') }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-arrow-left"></i> Retour à la liste des entreprises
</a>
</div>
</div>
{{ include('company/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,50 +1,41 @@
{% extends 'base.html.twig' %}
{% block title %}Liste des Entreprises{% endblock %}
{% block title %}Company index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des Entreprises</h1>
<h1>Company index</h1>
<div class="overflow-x-auto bg-white shadow-lg rounded-lg">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-800 text-white">
<th class="px-4 py-2 text-left">ID</th>
<th class="px-4 py-2 text-left">Nom de l'entreprise</th>
<th class="px-4 py-2 text-left">Actions</th>
</tr>
</thead>
<tbody>
{% for company in companies %}
<tr class="border-b">
<td class="px-4 py-2">{{ company.id }}</td>
<td class="px-4 py-2">{{ company.name }}</td>
<td class="px-4 py-2 flex items-center gap-4">
<a href="{{ path('app_company_show', {'id': company.id}) }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-eye"></i> Voir
</a>
<a href="{{ path('app_company_edit', {'id': company.id}) }}" class="text-yellow-500 hover:text-yellow-700">
<i class="fas fa-edit"></i> Modifier
</a>
<form method="post" action="{{ path('app_company_delete', {'id': company.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ company.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Address</th>
<th>Tel</th>
<th>Mail</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for company in companies %}
<tr>
<td>{{ company.id }}</td>
<td>{{ company.name }}</td>
<td>{{ company.address }}</td>
<td>{{ company.tel }}</td>
<td>{{ company.mail }}</td>
<td>
<a href="{{ path('app_company_show', {'id': company.id}) }}">show</a>
<a href="{{ path('app_company_edit', {'id': company.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="6">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="mt-4">
<a href="{{ path('app_company_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
<i class="fas fa-plus-circle"></i> Ajouter une nouvelle entreprise
</a>
</div>
</div>
<a href="{{ path('app_company_new') }}">Create new</a>
{% endblock %}

View File

@ -1,47 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Nouvelle Entreprise{% endblock %}
{% block title %}New Company{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6">Créer une nouvelle entreprise</h1>
<h1>Create new Company</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('company/_form.html.twig') }}
<div class="mb-4">
<label for="company_name" class="block text-lg font-medium text-gray-700 mb-2">Nom de l'entreprise</label>
{{ form_widget(form.name, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
<div class="mb-4">
<label for="company_address" class="block text-lg font-medium text-gray-700 mb-2">Adresse de l'entreprise</label>
{{ form_widget(form.address, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
<div class="mb-4">
<label for="company_tel" class="block text-lg font-medium text-gray-700 mb-2">Numéro de téléphone</label>
{{ form_widget(form.tel, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
<div class="mb-4">
<label for="company_mail" class="block text-lg font-medium text-gray-700 mb-2">Email de l'entreprise</label>
{{ form_widget(form.mail, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Créer l'entreprise
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-4">
<a href="{{ path('app_company_index') }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-arrow-left"></i> Retour à la liste des entreprises
</a>
</div>
</div>
<a href="{{ path('app_company_index') }}">back to list</a>
{% endblock %}

View File

@ -1,56 +1,38 @@
{% extends 'base.html.twig' %}
{% block title %}Détail de l'entreprise{% endblock %}
{% block title %}Company{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Détail de l'entreprise</h1>
<h1>Company</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<table class="min-w-full">
<tbody>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">ID</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ company.id }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Nom</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ company.name }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Adresse</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ company.address }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Téléphone</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ company.tel }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Email</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ company.mail }}</td>
</tr>
</tbody>
</table>
</div>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ company.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ company.name }}</td>
</tr>
<tr>
<th>Address</th>
<td>{{ company.address }}</td>
</tr>
<tr>
<th>Tel</th>
<td>{{ company.tel }}</td>
</tr>
<tr>
<th>Mail</th>
<td>{{ company.mail }}</td>
</tr>
</tbody>
</table>
<div class="mt-6 flex justify-between">
<a href="{{ path('app_company_index') }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-arrow-left"></i> Retour à la liste des entreprises
</a>
<a href="{{ path('app_company_index') }}">back to list</a>
<a href="{{ path('app_company_edit', {'id': company.id}) }}" class="text-yellow-500 hover:text-yellow-700">
<i class="fas fa-edit"></i> Modifier cette entreprise
</a>
</div>
<a href="{{ path('app_company_edit', {'id': company.id}) }}">edit</a>
<div class="mt-6">
<form method="post" action="{{ path('app_company_delete', {'id': company.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ company.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer cette entreprise
</button>
</form>
</div>
</div>
{{ include('company/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,36 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier un Diplôme{% endblock %}
{% block title %}Edit Degree{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Modifier le Diplôme</h1>
<h1>Edit Degree</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<h2 class="text-2xl font-medium text-gray-700 mb-6">Modifier les informations du diplôme</h2>
{{ include('degree/_form.html.twig', {'button_label': 'Update'}) }}
{{ form_start(form) }}
<div class="mb-4">
<label for="degree_label" class="block text-lg font-medium text-gray-700 mb-2">Label du diplôme</label>
<div class="mt-1">
{{ form_widget(form.label, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<a href="{{ path('app_degree_index') }}">back to list</a>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Mettre à jour
</button>
</div>
{{ form_end(form) }}
<div class="mt-6 flex justify-between">
<a href="{{ path('app_degree_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des diplômes
</a>
{{ include('degree/_delete_form.html.twig') }}
</div>
</div>
{% endblock %}
{{ include('degree/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,57 +1,35 @@
{% extends 'base.html.twig' %}
{% block title %}List of Degrees{% endblock %}
{% block title %}Degree index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des Diplômes</h1>
<h1>Degree index</h1>
<!-- Tableau des diplômes -->
<div class="overflow-x-auto bg-white shadow-lg rounded-lg">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-800 text-white">
<th class="px-4 py-2 text-left">ID</th>
<th class="px-4 py-2 text-left">Label</th>
<th class="px-4 py-2 text-left">Actions</th>
</tr>
</thead>
<tbody>
{% for degree in degrees %}
<tr class="border-b">
<td class="px-4 py-2">{{ degree.id }}</td>
<td class="px-4 py-2">{{ degree.label }}</td>
<td class="px-4 py-2">
<!-- Voir le diplôme -->
<a href="{{ path('app_degree_show', {'id': degree.id}) }}" class="text-teal-500 hover:text-teal-700 mr-3">
<i class="fas fa-eye"></i> Voir
</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Label</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for degree in degrees %}
<tr>
<td>{{ degree.id }}</td>
<td>{{ degree.label }}</td>
<td>
<a href="{{ path('app_degree_show', {'id': degree.id}) }}">show</a>
<a href="{{ path('app_degree_edit', {'id': degree.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="3">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Modifier le diplôme -->
<a href="{{ path('app_degree_edit', {'id': degree.id}) }}" class="text-yellow-500 hover:text-yellow-700 mr-3">
<i class="fas fa-edit"></i> Modifier
</a>
<!-- Formulaire pour supprimer le diplôme -->
<form method="post" action="{{ path('app_degree_delete', {'id': degree.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ degree.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Lien pour ajouter un nouveau diplôme -->
<div class="mt-4">
<a href="{{ path('app_degree_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
<i class="fas fa-plus-circle"></i> Ajouter un nouveau diplôme
</a>
</div>
</div>
<a href="{{ path('app_degree_new') }}">Create new</a>
{% endblock %}

View File

@ -1,34 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Créer un Nouveau Diplôme{% endblock %}
{% block title %}New Degree{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Créer un Nouveau Diplôme</h1>
<h1>Create new Degree</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('degree/_form.html.twig') }}
<div class="mb-6">
<label for="degree_label" class="block text-lg font-medium text-gray-700 mb-2">Label du Diplôme</label>
<div class="mt-1">
{{ form_widget(form.label, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Créer le Diplôme
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_degree_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des diplômes
</a>
</div>
</div>
<a href="{{ path('app_degree_index') }}">back to list</a>
{% endblock %}

View File

@ -1,42 +1,26 @@
{% extends 'base.html.twig' %}
{% block title %}Détail du Diplôme{% endblock %}
{% block title %}Degree{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Détail du Diplôme</h1>
<h1>Degree</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<table class="min-w-full">
<tbody>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">ID</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ degree.id }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Label</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ degree.label }}</td>
</tr>
</tbody>
</table>
</div>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ degree.id }}</td>
</tr>
<tr>
<th>Label</th>
<td>{{ degree.label }}</td>
</tr>
</tbody>
</table>
<div class="mt-6 flex justify-between">
<a href="{{ path('app_degree_index') }}"
class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des diplômes
</a>
<a href="{{ path('app_degree_index') }}">back to list</a>
<div class="flex items-center space-x-4">
<a href="{{ path('app_degree_edit', {'id': degree.id}) }}"
class="text-yellow-500 hover:text-yellow-700 text-lg">
<i class="fas fa-edit"></i> Modifier ce diplôme
</a>
<a href="{{ path('app_degree_delete', {'id': degree.id}) }}"
class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg">
<i class="fas fa-trash-alt"></i> Supprimer
</a>
</div>
</div>
</div>
<a href="{{ path('app_degree_edit', {'id': degree.id}) }}">edit</a>
{{ include('degree/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,40 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier la FAQ{% endblock %}
{% block title %}Edit FAQ{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Modifier la FAQ</h1>
<h1>Edit FAQ</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('faq/_form.html.twig', {'button_label': 'Update'}) }}
<div class="mb-4">
<label for="faq_question" class="block text-lg font-medium text-gray-700 mb-2">Question</label>
<div class="mt-1">
{{ form_widget(form.question, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<a href="{{ path('app_faq_index') }}">back to list</a>
<div class="mb-4">
<label for="faq_answer" class="block text-lg font-medium text-gray-700 mb-2">Réponse</label>
<div class="mt-1">
{{ form_widget(form.answer, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Mettre à jour la FAQ
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_faq_index') }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-arrow-left"></i> Retour à la liste des FAQs
</a>
</div>
</div>
{{ include('faq/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,55 +1,39 @@
{% extends 'base.html.twig' %}
{% block title %}Liste des FAQs{% endblock %}
{% block title %}FAQ index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des FAQs</h1>
<h1>FAQ index</h1>
<div class="overflow-x-auto bg-white shadow-lg rounded-lg">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-800 text-white">
<th class="px-4 py-2 text-left">Question</th>
<th class="px-4 py-2 text-left">Réponse</th>
<th class="px-4 py-2 text-left">Denrnière modif</th>
<th class="px-4 py-2 text-left">Actions</th>
</tr>
</thead>
<tbody>
{% for faq in faqs %}
<tr class="border-b">
<td class="px-4 py-2">{{ faq.question }}</td>
<td class="px-4 py-2">{{ faq.answer }}</td>
<td class="px-4 py-2">{{ faq.updateDate|date("d-m-y") }}</td>
<td class="px-4 py-2">
<a href="{{ path('app_faq_show', {'id': faq.id}) }}" class="text-teal-500 hover:text-teal-700 mr-3">
<i class="fas fa-eye"></i> Voir
</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Question</th>
<th>Answer</th>
<th>UpdateDate</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for faq in faqs %}
<tr>
<td>{{ faq.id }}</td>
<td>{{ faq.question }}</td>
<td>{{ faq.answer }}</td>
<td>{{ faq.updateDate ? faq.updateDate|date('Y-m-d') : '' }}</td>
<td>
<a href="{{ path('app_faq_show', {'id': faq.id}) }}">show</a>
<a href="{{ path('app_faq_edit', {'id': faq.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="5">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_faq_edit', {'id': faq.id}) }}" class="text-yellow-500 hover:text-yellow-700 mr-3">
<i class="fas fa-edit"></i> Modifier
</a>
<form method="post" action="{{ path('app_faq_delete', {'id': faq.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ faq.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="mt-4">
<a href="{{ path('app_faq_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
<i class="fas fa-plus-circle"></i> Ajouter une FAQ
</a>
</div>
</div>
<a href="{{ path('app_faq_new') }}">Create new</a>
{% endblock %}

View File

@ -1,40 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Créer une FAQ{% endblock %}
{% block title %}New FAQ{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Créer une nouvelle FAQ</h1>
<h1>Create new FAQ</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('faq/_form.html.twig') }}
<div class="mb-4">
<label for="faq_question" class="block text-lg font-medium text-gray-700 mb-2">Question</label>
<div class="mt-1">
{{ form_widget(form.question, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mb-4">
<label for="faq_answer" class="block text-lg font-medium text-gray-700 mb-2">Réponse</label>
<div class="mt-1">
{{ form_widget(form.answer, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Créer la FAQ
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_faq_index') }}" class="text-teal-500 hover:text-teal-700">
<i class="fas fa-arrow-left"></i> Retour à la liste des FAQs
</a>
</div>
</div>
<a href="{{ path('app_faq_index') }}">back to list</a>
{% endblock %}

View File

@ -1,48 +1,34 @@
{% extends 'base.html.twig' %}
{% block title %}Détail de la FAQ{% endblock %}
{% block title %}FAQ{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Détail de la FAQ</h1>
<h1>FAQ</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<table class="min-w-full">
<tbody>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">ID</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ faq.id }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Question</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ faq.question }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Réponse</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ faq.answer }}</td>
</tr>
</tbody>
</table>
</div>
<div class="mt-6 flex justify-between">
<!-- Bouton Retour à la liste -->
<a href="{{ path('app_faq_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des FAQs
</a>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ faq.id }}</td>
</tr>
<tr>
<th>Question</th>
<td>{{ faq.question }}</td>
</tr>
<tr>
<th>Answer</th>
<td>{{ faq.answer }}</td>
</tr>
<tr>
<th>UpdateDate</th>
<td>{{ faq.updateDate ? faq.updateDate|date('Y-m-d') : '' }}</td>
</tr>
</tbody>
</table>
<!-- Boutons Modifier et Supprimer -->
<div class="flex items-center space-x-4">
<a href="{{ path('app_faq_edit', {'id': faq.id}) }}" class="text-yellow-500 hover:text-yellow-700 text-lg">
<i class="fas fa-edit"></i> Modifier cette FAQ
</a>
<form method="post" action="{{ path('app_faq_delete', {'id': faq.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ faq.id) }}">
<button type="submit" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</div>
</div>
</div>
{% endblock %}
<a href="{{ path('app_faq_index') }}">back to list</a>
<a href="{{ path('app_faq_edit', {'id': faq.id}) }}">edit</a>
{{ include('faq/_delete_form.html.twig') }}
{% endblock %}

View File

@ -24,7 +24,6 @@
</label>
<button class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-6 rounded">Trouvez un stage</button>
</div>
<p class="text-black"> la recherche n'est pas encore implémenté </p>
</div>
<div class="flex justify-center space-x-8 mt-8">
<div class="text-center">
@ -57,4 +56,39 @@
var marker = L.marker([coordX,coordY]).addTo(map).bindPopup(name);
{% endfor %}
</script>
<section class="container mx-auto py-12">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold">Propositions de stages </h2>
<a class="text-teal-500 hover:underline" href="{{ path('app_announcement_list') }}">Voir tout</a>
</div>
<div class="space-y-6">
{# Loop over recent offers (replace with dynamic data)
{% for offer in recent_offers %}
<div class="bg-white p-6 rounded-lg shadow flex justify-between items-center">
<div class="flex items-center space-x-4">
<div class="text-gray-500 text-sm">{{ offer.time_ago }}</div>
<div>
<h3 class="text-lg font-bold">{{ offer.title }}</h3>
<p class="text-gray-600">{{ offer.company }}</p>
<div class="flex items-center space-x-2 text-gray-500 text-sm mt-2">
<span class="flex items-center">
<i class="fas fa-briefcase mr-1"></i> {{ offer.category }}
</span>
<span class="flex items-center">
<i class="fas fa-clock mr-1"></i> {{ offer.type }}
</span>
<span class="flex items-center">
<i class="fas fa-dollar-sign mr-1"></i> {{ offer.salary }}
</span>
<span class="flex items-center">
<i class="fas fa-map-marker-alt mr-1"></i> {{ offer.location }}
</span>
</div>
</div>
</div>
<button class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded">Détails de l'offre</button>
</div>
{% endfor %}#}
</div>
</section>
{% endblock %}

View File

@ -1,29 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Conversation{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6 text-center">Conversation avec {{ receiver.nickname }}</h1>
<div class="conversation bg-gray-100 p-6 rounded-lg shadow-lg">
{% for msg in conversation %}
<div class="message {% if msg.sender == app.user %}bg-teal-500 text-white self-end{% else %}bg-gray-200 text-gray-700 self-start{% endif %} p-4 my-2 rounded-lg max-w-xs">
<p class="font-semibold">{{ msg.sender.nickname }} :</p>
<p class="mt-2">{{ msg.content }}</p>
<p class="text-xs text-gray-500 mt-2">{{ msg.sendingDate|date('Y-m-d H:i:s') }}</p>
</div>
{% endfor %}
</div>
<!-- Bouton pour répondre -->
<div class="mt-4 text-center">
<a href="{{ path('app_message_new', {'receiverId': receiverId}) }}" class="bg-teal-500 text-white px-6 py-3 rounded-md hover:bg-teal-600">
Répondre
</a>
</div>
<a href="{{ path('app_message_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des Messages
</a>
</div>
{% endblock %}

View File

@ -1,39 +1,37 @@
{% extends 'base.html.twig' %}
{% block title %}Boîte de Réception{% endblock %}
{% block title %}Message index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6 text-center">Boîte de Réception</h1>
<h1>Message index</h1>
<!-- Bouton pour écrire un nouveau message -->
<div class="mb-6 text-center">
<a href="{{ path('app_message_new', {'receiverId': app.user.id}) }}" class="bg-teal-500 text-white px-6 py-3 rounded-md hover:bg-teal-600">
Écrire un Nouveau Message
</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Content</th>
<th>SendingDate</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for message in messages %}
<tr>
<td>{{ message.id }}</td>
<td>{{ message.content }}</td>
<td>{{ message.sendingDate ? message.sendingDate|date('Y-m-d H:i:s') : '' }}</td>
<td>
<a href="{{ path('app_message_show', {'id': message.id}) }}">show</a>
<a href="{{ path('app_message_edit', {'id': message.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="4">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Liste des messages reçus -->
<div class="max-w-4xl mx-auto">
{% for message in messages %}
{% if message.receiver == app.user or message.sender == app.user %}
<div class="bg-white p-6 rounded-lg shadow mb-4">
<div class="flex justify-between items-center">
<div>
<h2 class="text-xl font-semibold">De : {{ message.sender.nickname }}</h2>
<p class="text-gray-600">{{ message.sendingDate|date('d/m/Y H:i') }}</p>
</div>
<a href="{{ path('app_message_conversation', { id: message.id }) }}" class="bg-teal-500 text-white px-4 py-2 rounded hover:bg-teal-600">
Voir la Conversation
</a>
</div>
<p class="mt-4 text-gray-700">{{ message.content }}</p>
</div>
{% endif %}
{% else %}
<p class="text-center text-gray-500">Vous n'avez reçu aucun message.</p>
{% endfor %}
</div>
</div>
<a href="{{ path('app_message_new') }}">Create new</a>
{% endblock %}

View File

@ -1,27 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Nouveau Message{% endblock %}
{% block title %}New Message{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6 text-center">Écrire un Nouveau Message</h1>
<h1>Create new Message</h1>
<div class="max-w-lg mx-auto bg-white p-6 rounded-lg shadow">
{{ form_start(form) }}
<div class="mb-4">
<label class="block text-gray-700 font-medium mb-2">Destinataire</label>
{{ form_widget(form.receiver, {'attr': {'class': 'w-full p-3 border rounded'}}) }}
</div>
{{ include('message/_form.html.twig') }}
<div class="mb-4">
<label class="block text-gray-700 font-medium mb-2">Message</label>
{{ form_widget(form.content, {'attr': {'class': 'w-full p-3 border rounded', 'rows': 6}}) }}
</div>
<button type="submit" class="w-full bg-teal-500 text-white px-4 py-2 rounded hover:bg-teal-600">
Envoyer
</button>
{{ form_end(form) }}
</div>
</div>
{% endblock %}
<a href="{{ path('app_message_index') }}">back to list</a>
{% endblock %}

View File

@ -1,28 +1,30 @@
{% extends 'base.html.twig' %}
{% block title %}Voir le Message{% endblock %}
{% block title %}Message{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-6 text-center">Message de {{ message.sender.nickname }}</h1>
<h1>Message</h1>
<div class="max-w-lg mx-auto bg-white p-6 rounded-lg shadow">
<div class="mb-4">
<p class="text-gray-700"><strong>De :</strong> {{ message.sender.nickname }}</p>
<p class="text-gray-700"><strong>Reçu le :</strong> {{ message.sendingDate|date('d/m/Y H:i') }}</p>
</div>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ message.id }}</td>
</tr>
<tr>
<th>Content</th>
<td>{{ message.content }}</td>
</tr>
<tr>
<th>SendingDate</th>
<td>{{ message.sendingDate ? message.sendingDate|date('Y-m-d H:i:s') : '' }}</td>
</tr>
</tbody>
</table>
<div class="bg-gray-100 p-4 rounded mb-6">
<p class="text-gray-800 whitespace-pre-line">{{ message.content }}</p>
</div>
<a href="{{ path('app_message_index') }}">back to list</a>
<!-- Bouton pour répondre -->
<div class="text-center">
<a href="{{ path('app_message_new', {'receiver': message.sender.id}) }}"
class="bg-teal-500 text-white px-6 py-2 rounded hover:bg-teal-600">
Répondre
</a>
</div>
</div>
</div>
{% endblock %}
<a href="{{ path('app_message_edit', {'id': message.id}) }}">edit</a>
{{ include('message/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,32 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier l'utilisateur{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Modifier l'utilisateur</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
<div class="space-y-6">
{{ form_row(form.nickname, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.firstName, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.lastName, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.tel, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.address, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.mail, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.password, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
</div>
<div class="mt-6">
{{ form_widget(form) }}
</div>
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white px-6 py-3 rounded-lg mt-4">
Mettre à jour
</button>
{{ form_end(form) }}
</div>
</div>
{% endblock %}

View File

@ -1,7 +0,0 @@
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4">Bonjour {{ app.user.firstName }} {{ app.user.lastName }}</h2>
<p class="text-gray-700">Vous êtes employé(e) chez {{ app.user.company }}.</p>
<p class="text-gray-600">Adresse : {{ app.user.address }}</p>
<p class="text-gray-600">Téléphone : {{ app.user.tel }}</p>
<p class="text-gray-600">Email : {{ app.user.mail }}</p>
</div>

View File

@ -1,25 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Profil{% endblock %}
{% block body %}
<div class="container mx-auto px-4 py-6">
<h1 class="text-2xl font-bold mb-4">Profil</h1>
<!-- Vue spécifique pour le stagiaire -->
{% if 'ROLE_INTERN' in app.user.roles %}
{% include 'profile/intern.html.twig' %}
{% endif %}
<!-- Vue spécifique pour l'employé -->
{% if 'ROLE_EMPLOYEE' in app.user.roles %}
{% include 'profile/employee.html.twig' %}
{% endif %}
{% if 'ROLE_ADMIN' in app.user.roles%}
<div>
<h1 class="text-9xl font-bold ml-kdn "> Vous etes admin</h1>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -1,53 +0,0 @@
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4">Bonjour {{ app.user.nickname }}</h2>
<p class="text-gray-700">Vous êtes à la recherche d'un stage.</p>
<br>
<p class="text-gray-600">Nom : {{ app.user.firstName }}</p>
<p class="text-gray-600">Prénom : {{ app.user.lastName }}</p>
<p class="text-gray-600">Adresse : {{ app.user.address }}</p>
<p class="text-gray-600">Téléphone : {{ app.user.tel }}</p>
<p class="text-gray-600">Email : {{ app.user.mail }}</p>
<h3 class="text-lg font-semibold mt-6">Vos diplômes :</h3>
<ul class="list-disc list-inside text-gray-800">
{% if app.user.degrees|length > 0 %}
{% for deg in app.user.degrees %}
<li>{{ deg.label }}</li>
{% endfor %}
{% else %}
<br>
Aucun pour le moment
{% endif %}
</ul>
<br>
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"
href="{{ path('app_user_edit',{id: app.user.id}) }}"> Selectionner vos diplômes
</a>
<h3 class="text-lg font-semibold mt-6">Vos compétences :</h3>
<ul class="list-disc list-inside text-gray-800">
{% if app.user.skills|length > 0 %}
{% for comp in app.user.skills %}
<li>{{ comp.label }}</li>
{% endfor %}
{% else %}
<br>
Aucune pour le moment
{% endif %}
</ul>
<br>
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"
href="{{ path('app_user_edit',{id: app.user.id}) }}"> Selectionner vos compétences
</a>
<div class="flex justify-center mt-6">
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"
href="{{ path('app_user_edit',{id: app.user.id}) }}"> Accéder aux favoris
</a>
</div>
<div class="flex justify-end mt-6">
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"
href="{{ path('app_profile_edit',{id: app.user.id}) }}"> Modifier
</a>
</div>
</div>

View File

@ -7,10 +7,10 @@
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h2 class="text-2xl font-bold text-center mb-2">Connexion</h2>
<p class="text-center text-gray-600 mb-6">
Pas encore inscrit ? Inscrivez vous ! <br>
<a href="{{ path('app_register_intern') }}" class="text-teal-600 hover:underline">En tant que Stagiaire</a>
|
<a href="{{ path('app_register_employee') }}" class="text-teal-600 hover:underline">En tant qu'Entreprise</a>
Pas encore inscrit ? Inscrivez vous !! <br>
<a href="{{ path('app_register_intern') }}" class="text-teal-600 hover:underline">En tant que stagiaire</a>
<br>
<a href="{{ path('app_register_employee') }}" class="text-teal-600 hover:underline">En tant qu'entreprise</a>
</p>
<form method="post">

View File

@ -1,48 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier la compétence{% endblock %}
{% block title %}Edit Skill{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Modifier la compétence</h1>
<h1>Edit Skill</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<h2 class="text-2xl font-medium text-gray-700 mb-6">Modifier les informations de la compétence</h2>
{{ include('skill/_form.html.twig', {'button_label': 'Update'}) }}
{{ form_start(form) }}
<div class="mb-4">
<label for="skill_label" class="block text-lg font-medium text-gray-700 mb-2">Label de la compétence</label>
<div class="mt-1">
{{ form_widget(form.label, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<a href="{{ path('app_skill_index') }}">back to list</a>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Mettre à jour
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6 flex justify-between items-center">
<a href="{{ path('app_skill_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des compétences
</a>
<div class="flex items-center space-x-4">
<a href="{{ path('app_skill_show', {'id': skill.id}) }}" class="bg-yellow-500 hover:bg-yellow-600 text-white px-4 py-2 rounded-lg">
Voir la compétence
</a>
<form method="post" action="{{ path('app_skill_delete', {'id': skill.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ skill.id) }}">
<button type="submit" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg">
Supprimer
</button>
</form>
</div>
</div>
</div>
{{ include('skill/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,52 +1,35 @@
{% extends 'base.html.twig' %}
{% block title %}Liste des Compétences{% endblock %}
{% block title %}Skill index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des Compétences</h1>
<h1>Skill index</h1>
<div class="overflow-x-auto bg-white shadow-lg rounded-lg">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-800 text-white">
<th class="px-4 py-2 text-left">ID</th>
<th class="px-4 py-2 text-left">Label</th>
<th class="px-4 py-2 text-left">Actions</th>
</tr>
</thead>
<tbody>
{% for skill in skills %}
<tr class="border-b">
<td class="px-4 py-2">{{ skill.id }}</td>
<td class="px-4 py-2">{{ skill.label }}</td>
<td class="px-4 py-2">
<a href="{{ path('app_skill_show', {'id': skill.id}) }}" class="text-teal-500 hover:text-teal-700 mr-3">
<i class="fas fa-eye"></i> Voir
</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Label</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for skill in skills %}
<tr>
<td>{{ skill.id }}</td>
<td>{{ skill.label }}</td>
<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="3">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}" class="text-yellow-500 hover:text-yellow-700 mr-3">
<i class="fas fa-edit"></i> Modifier
</a>
<form method="post" action="{{ path('app_skill_delete', {'id': skill.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ skill.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="mt-4">
<a href="{{ path('app_skill_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
<i class="fas fa-plus-circle"></i> Ajouter une nouvelle compétence
</a>
</div>
</div>
<a href="{{ path('app_skill_new') }}">Create new</a>
{% endblock %}

View File

@ -1,34 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Créer une Nouvelle Compétence{% endblock %}
{% block title %}New Skill{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Créer une Nouvelle Compétence</h1>
<h1>Create new Skill</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('skill/_form.html.twig') }}
<div class="mb-6">
<label for="skill_label" class="block text-lg font-medium text-gray-700 mb-2">Label de la compétence</label>
<div class="mt-1">
{{ form_widget(form.label, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Créer la Compétence
</button>
</div>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_skill_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des compétences
</a>
</div>
</div>
<a href="{{ path('app_skill_index') }}">back to list</a>
{% endblock %}

View File

@ -1,34 +1,26 @@
{% extends 'base.html.twig' %}
{% block title %}Créer une Nouvelle Compétence{% endblock %}
{% block title %}Skill{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Créer une Nouvelle Compétence</h1>
<h1>Skill</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ skill.id }}</td>
</tr>
<tr>
<th>Label</th>
<td>{{ skill.label }}</td>
</tr>
</tbody>
</table>
<div class="mb-6">
<label for="skill_label" class="block text-lg font-medium text-gray-700 mb-2">Label de la compétence</label>
<div class="mt-1">
{{ form_widget(form.label, {'attr': {'class': 'block w-full p-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
</div>
</div>
<a href="{{ path('app_skill_index') }}">back to list</a>
<div class="mt-6">
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full w-full">
Créer la Compétence
</button>
</div>
<a href="{{ path('app_skill_edit', {'id': skill.id}) }}">edit</a>
{{ form_end(form) }}
</div>
<div class="mt-6">
<a href="{{ path('app_skill_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des compétences
</a>
</div>
</div>
{{ include('skill/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,49 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}Modifier l'utilisateur{% endblock %}
{% block title %}Edit UserApp{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Modifier l'utilisateur</h1>
<h1>Edit UserApp</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form) }}
{{ include('user_app/_form.html.twig', {'button_label': 'Update'}) }}
<div class="space-y-6">
{{ form_row(form.nickname, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.firstName, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.lastName, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.tel, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.address, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.mail, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.password, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
</div>
<a href="{{ path('app_user_app_index') }}">back to list</a>
<div class="mt-6">
{{ form_widget(form) }}
</div>
<button type="submit" class="bg-teal-500 hover:bg-teal-600 text-white px-6 py-3 rounded-lg mt-4">
Mettre à jour
</button>
{{ form_end(form) }}
</div>
<div class="mt-6 flex justify-between items-center">
<a href="{{ path('app_user_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des utilisateurs
</a>
<div class="flex items-center space-x-4">
<a href="{{ path('app_user_show', {'id': user_app.id}) }}" class="bg-yellow-500 hover:bg-yellow-600 text-white px-4 py-2 rounded-lg">
Voir l'utilisateur
</a>
<a href="{{ path('app_user_delete', {'id': user_app.id}) }}" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg">
Supprimer
</a>
</div>
</div>
</div>
{{ include('user_app/_delete_form.html.twig') }}
{% endblock %}

View File

@ -1,56 +1,49 @@
{% extends 'base.html.twig' %}
{% block title %}Liste des utilisateurs{% endblock %}
{% block title %}UserApp index{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des Utilisateurs</h1>
<h1>UserApp index</h1>
<div class="overflow-x-auto bg-white shadow-lg rounded-lg">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-800 text-white">
<th class="px-4 py-2 text-left">ID</th>
<th class="px-4 py-2 text-left">Nickname</th>
<th class="px-4 py-2 text-left">FirstName</th>
<th class="px-4 py-2 text-left">LastName</th>
<th class="px-4 py-2 text-left">Mail</th>
<th class="px-4 py-2 text-left">Actions</th>
</tr>
</thead>
<tbody>
{% for user_app in user_apps %}
<tr class="border-b">
<td class="px-4 py-2">{{ user_app.id }}</td>
<td class="px-4 py-2">{{ user_app.nickname }}</td>
<td class="px-4 py-2">{{ user_app.firstName }}</td>
<td class="px-4 py-2">{{ user_app.lastName }}</td>
<td class="px-4 py-2">{{ user_app.mail }}</td>
<td class="px-4 py-2">
<a href="{{ path('app_user_show', {'id': user_app.id}) }}" class="text-teal-500 hover:text-teal-700 mr-3">
<i class="fas fa-eye"></i> Voir
</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Nickname</th>
<th>Roles</th>
<th>Password</th>
<th>FirstName</th>
<th>LastName</th>
<th>Tel</th>
<th>Address</th>
<th>Mail</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for user_app in user_apps %}
<tr>
<td>{{ user_app.id }}</td>
<td>{{ user_app.nickname }}</td>
<td>{{ user_app.roles ? user_app.roles|json_encode : '' }}</td>
<td>{{ user_app.password }}</td>
<td>{{ user_app.firstName }}</td>
<td>{{ user_app.lastName }}</td>
<td>{{ user_app.tel }}</td>
<td>{{ user_app.address }}</td>
<td>{{ user_app.mail }}</td>
<td>
<a href="{{ path('app_user_app_show', {'id': user_app.id}) }}">show</a>
<a href="{{ path('app_user_app_edit', {'id': user_app.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="10">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_user_edit', {'id': user_app.id}) }}" class="text-yellow-500 hover:text-yellow-700 mr-3">
<i class="fas fa-edit"></i> Modifier
</a>
<form method="post" action="{{ path('app_user_delete', {'id': user_app.id}) }}" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ user_app.id) }}">
<button type="submit" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash-alt"></i> Supprimer
</button>
</form>
</td>
</tr>
{% else %}
<tr>
<td colspan="6" class="text-center py-4">Aucun utilisateur trouvé</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
<a href="{{ path('app_user_app_new') }}">Create new</a>
{% endblock %}

View File

@ -1,58 +1,42 @@
{% extends 'base.html.twig' %}
{% block title %}Détail de l'utilisateur{% endblock %}
{% block title %}UserApp{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Détail de l'utilisateur</h1>
<div class="bg-white shadow-md rounded-lg p-6">
<table class="min-w-full">
<tbody>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">ID</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.id }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Nom</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.lastName }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Prénom</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.firstName }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Téléphone</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.tel }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">Adresse</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.address }}</td>
</tr>
<tr class="border-b">
<th class="px-6 py-4 text-lg font-medium text-gray-700">E-mail</th>
<td class="px-6 py-4 text-lg text-gray-900">{{ user_app.mail }}</td>
</tr>
</tbody>
</table>
<div class="gap-y-5">
<div class="flex gap-x-5">
<p class="font-bold">Nom d'utilisateur : </p>
<p>{{ user_app.nickname }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Rôles : </p>
<p>{{ user_app.roles ? user_app.roles|json_encode : '' }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Prénom : </p>
<p>{{ user_app.firstName }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Nom : </p>
<p>{{ user_app.lastName }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Téléphone : </p>
<p>{{ user_app.tel }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Addresse : </p>
<p>{{ user_app.address }}</p>
</div>
<div class="flex gap-x-5">
<p class="font-bold">Mail : </p>
<p>{{ user_app.mail }}</p>
</div>
<div class="mt-6 flex justify-between">
<a href="{{ path('app_user_index') }}" class="text-teal-500 hover:text-teal-700 text-lg">
<i class="fas fa-arrow-left"></i> Retour à la liste des utilisateurs
</a>
<a href="{{ path('app_user_app_edit', {'id': user_app.id}) }}">Modifier</a>
<div class="flex items-center space-x-4">
<a href="{{ path('app_user_edit', {'id': user_app.id}) }}"
class="text-yellow-500 hover:text-yellow-700 text-lg">
<i class="fas fa-edit"></i> Modifier cet utilisateur
</a>
<a href="{{ path('app_user_delete', {'id': user_app.id}) }}"
class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg">
<i class="fas fa-trash-alt"></i> Supprimer
</a>
</div>
</div>
{{ include('user_app/_delete_form.html.twig') }}
</div>
{% endblock %}
{% endblock %}