Compare commits

..

6 Commits

Author SHA1 Message Date
958070bd54 vue cv 2025-04-08 12:05:33 +02:00
0861ed2112 add resume and show 2025-04-08 11:41:15 +02:00
120906c0c5 Add resume and modify entity 2025-04-08 11:03:46 +02:00
911f3a24cc Update FAQ 2025-04-08 09:10:36 +02:00
0a85c0854b faq page 2025-04-08 08:54:18 +02:00
30f58aca76 pull branch romain 2025-04-08 08:54:18 +02:00
38 changed files with 428 additions and 450 deletions

View File

@ -1,7 +1,7 @@
security: security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers: password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' # à mettre en auto pour sécuriser les mdp Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'plaintext' # à mettre en auto pour sécuriser les mdp
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers: providers:
# used to reload user from session & other features (e.g. switch_user) # used to reload user from session & other features (e.g. switch_user)

View File

@ -5,6 +5,7 @@
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration # https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters: parameters:
app.jwtsecret : '%env(JWT_SECRET)%' app.jwtsecret : '%env(JWT_SECRET)%'
cv_directory: '%kernel.project_dir%/public/cv'
services: services:
# default configuration for services in *this* file # default configuration for services in *this* file
_defaults: _defaults:

View File

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

Binary file not shown.

Binary file not shown.

View File

@ -3,10 +3,8 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Announcement; use App\Entity\Announcement;
use App\Entity\Employee;
use App\Form\AnnouncementType; use App\Form\AnnouncementType;
use App\Repository\AnnouncementRepository; use App\Repository\AnnouncementRepository;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -16,13 +14,8 @@ use Symfony\Component\Routing\Attribute\Route;
#[Route('/announcement')] #[Route('/announcement')]
final class AnnouncementController extends AbstractController final class AnnouncementController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly AnnouncementRepository $announcementRepository,
){}
#[Route('/', name: 'app_announcement_index')] #[Route('/', name: 'app_announcement_index')]
public function list(Request $request,): Response public function list(Request $request, AnnouncementRepository $announcementRepository): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
$announcements = []; $announcements = [];
@ -35,9 +28,9 @@ final class AnnouncementController extends AbstractController
$showNonValidated = $request->query->get('show_non_validated'); $showNonValidated = $request->query->get('show_non_validated');
if ($showNonValidated) { if ($showNonValidated) {
$announcements = $this->announcementRepository->findBy(['status' => 'notVerified']); $announcements = $announcementRepository->findBy(['status' => 'notVerified']);
} else { } else {
$announcements = $this->announcementRepository->findAll(); $announcements = $announcementRepository->findAll();
} }
} }
@ -45,16 +38,16 @@ final class AnnouncementController extends AbstractController
$company = $user->getCompany(); $company = $user->getCompany();
if ($company) { if ($company) {
$announcements = $this->announcementRepository->findBy(['company' => $company]); $announcements = $announcementRepository->findBy(['company' => $company]);
} }
} }
if (in_array('ROLE_INTERN', $user->getRoles())) { if (in_array('ROLE_INTERN', $user->getRoles())) {
$announcements = $this->announcementRepository->findBy(['status' => 'Verified']); $announcements = $announcementRepository->findBy(['status' => 'Verified']);
} }
if ($companyName || $location || $category) { if ($companyName || $location || $category) {
$announcements = $this->announcementRepository->searchAnnouncements($companyName, $location, $category); $announcements = $announcementRepository->searchAnnouncements($companyName, $location, $category);
} }
$favorites = []; $favorites = [];
@ -75,15 +68,19 @@ final class AnnouncementController extends AbstractController
#[Route('/new', name: 'app_announcement_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_announcement_new', methods: ['GET', 'POST'])]
public function new(Request $request,): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$user = $this->getUser(); /*$user = $this->getUser();
if (!$user instanceof Employee) { if (in_array('ROLE_EMPLOYEE', $user->getRoles())) {
$this->addFlash('error', "Vous n'etes pas autorisé à faire cette action."); $company = $user->getCompany();
return $this->redirectToRoute('app_index');
} if (!$company)
$company = $user->getCompany(); {
echo "Compétez votre profile avant de créer une annonce";
$this->redirectToRoute('app_user_edit',['id' => $user->getId(),]);
}
}*/
$announcement = new Announcement(); $announcement = new Announcement();
$form = $this->createForm(AnnouncementType::class, $announcement); $form = $this->createForm(AnnouncementType::class, $announcement);
@ -92,9 +89,8 @@ final class AnnouncementController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$announcement->setCreationDate(new \DateTime()); $announcement->setCreationDate(new \DateTime());
$announcement->setStatus('notVerified'); $announcement->setStatus('notVerified');
$announcement->setCompany($company); $entityManager->persist($announcement);
$this->entityManager->persist($announcement); $entityManager->flush();
$this->entityManager->flush();
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
} }
@ -102,7 +98,6 @@ final class AnnouncementController extends AbstractController
return $this->render('announcement/new.html.twig', [ return $this->render('announcement/new.html.twig', [
'announcement' => $announcement, 'announcement' => $announcement,
'form' => $form, 'form' => $form,
'company' => $company,
]); ]);
} }
@ -115,13 +110,13 @@ final class AnnouncementController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_announcement_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_announcement_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Announcement $announcement,): Response public function edit(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(AnnouncementType::class, $announcement); $form = $this->createForm(AnnouncementType::class, $announcement);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
} }
@ -133,23 +128,23 @@ final class AnnouncementController extends AbstractController
} }
#[Route('/{id}', name: 'app_announcement_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_announcement_delete', methods: ['POST'])]
public function delete(Request $request, Announcement $announcement,): Response public function delete(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$announcement->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$announcement->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($announcement); $entityManager->remove($announcement);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_announcement_index', [], Response::HTTP_SEE_OTHER);
} }
#[Route('/{id}/validate', name: 'app_announcement_validate', methods: ['POST'])] #[Route('/{id}/validate', name: 'app_announcement_validate', methods: ['POST'])]
public function validate(Request $request, Announcement $announcement,): Response public function validate(Request $request, Announcement $announcement, EntityManagerInterface $entityManager): Response
{ {
if ($announcement->getStatus() !== 'Verified') if ($announcement->getStatus() !== 'Verified')
{ {
$announcement->setStatus('Verified'); $announcement->setStatus('Verified');
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_announcement_show', return $this->redirectToRoute('app_announcement_show',
['id' => $announcement->getId()], Response::HTTP_SEE_OTHER); ['id' => $announcement->getId()], Response::HTTP_SEE_OTHER);

View File

@ -4,9 +4,7 @@ namespace App\Controller;
use App\Entity\Company; use App\Entity\Company;
use App\Form\CompanyType; use App\Form\CompanyType;
use App\Repository\AnnouncementRepository;
use App\Repository\CompanyRepository; use App\Repository\CompanyRepository;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -17,29 +15,25 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
#[Route('/company')] #[Route('/company')]
final class CompanyController extends AbstractController final class CompanyController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly CompanyRepository $companyRepository,
){}
#[Route(name: 'app_company_index', methods: ['GET'])] #[Route(name: 'app_company_index', methods: ['GET'])]
public function index(): Response public function index(CompanyRepository $companyRepository): Response
{ {
return $this->render('company/index.html.twig', [ return $this->render('company/index.html.twig', [
'companies' => $this->companyRepository->findAll(), 'companies' => $companyRepository->findAll(),
]); ]);
} }
#[Route('/new', name: 'app_company_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_company_new', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function new(Request $request,): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$company = new Company(); $company = new Company();
$form = $this->createForm(CompanyType::class, $company); $form = $this->createForm(CompanyType::class, $company);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($company); $entityManager->persist($company);
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER);
} }
@ -60,13 +54,13 @@ final class CompanyController extends AbstractController
#[Route('/{id}/edit', name: 'app_company_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_company_edit', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function edit(Request $request, Company $company,): Response public function edit(Request $request, Company $company, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(CompanyType::class, $company); $form = $this->createForm(CompanyType::class, $company);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER);
} }
@ -78,11 +72,11 @@ final class CompanyController extends AbstractController
} }
#[Route('/{id}', name: 'app_company_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_company_delete', methods: ['POST'])]
public function delete(Request $request, Company $company,): Response public function delete(Request $request, Company $company, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$company->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$company->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($company); $entityManager->remove($company);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_company_index', [], Response::HTTP_SEE_OTHER);

View File

@ -5,9 +5,7 @@ namespace App\Controller;
use App\Entity\Degree; use App\Entity\Degree;
use App\Entity\InternDegree; use App\Entity\InternDegree;
use App\Form\DegreeType; use App\Form\DegreeType;
use App\Repository\AnnouncementRepository;
use App\Repository\DegreeRepository; use App\Repository\DegreeRepository;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -17,28 +15,24 @@ use Symfony\Component\Routing\Attribute\Route;
#[Route('/degree')] #[Route('/degree')]
final class DegreeController extends AbstractController final class DegreeController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly DegreeRepository $degreeRepository,
){}
#[Route(name: 'app_degree_index', methods: ['GET'])] #[Route(name: 'app_degree_index', methods: ['GET'])]
public function index(): Response public function index(DegreeRepository $degreeRepository): Response
{ {
return $this->render('degree/index.html.twig', [ return $this->render('degree/index.html.twig', [
'degrees' => $this->degreeRepository->findAll(), 'degrees' => $degreeRepository->findAll(),
]); ]);
} }
#[Route('/new', name: 'app_degree_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_degree_new', methods: ['GET', 'POST'])]
public function new(Request $request,): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$degree = new Degree(); $degree = new Degree();
$form = $this->createForm(DegreeType::class, $degree); $form = $this->createForm(DegreeType::class, $degree);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($degree); $entityManager->persist($degree);
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER);
} }
@ -58,13 +52,13 @@ final class DegreeController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_degree_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_degree_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Degree $degree,): Response public function edit(Request $request, Degree $degree, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(DegreeType::class, $degree); $form = $this->createForm(DegreeType::class, $degree);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER);
} }
@ -76,11 +70,11 @@ final class DegreeController extends AbstractController
} }
#[Route('/{id}', name: 'app_degree_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_degree_delete', methods: ['POST'])]
public function delete(Request $request, Degree $degree,): Response public function delete(Request $request, Degree $degree, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$degree->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$degree->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($degree); $entityManager->remove($degree);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_degree_index', [], Response::HTTP_SEE_OTHER);

View File

@ -92,31 +92,5 @@ final class EmployeeController extends AbstractController
]); ]);
} }
#[Route('/application/{id}/update-status/{status}', name: 'app_employee_update_application_status', methods: ['POST'])]
public function updateApplicationStatus(int $id, string $status): Response
{
$employee = $this->getUser();
if (!$employee instanceof Employee) {
throw $this->createAccessDeniedException('Seuls les employés peuvent accéder à cette action.');
}
$application = $this->internApplicationRepository->find($id);
if (!$application) {
throw $this->createNotFoundException('Candidature introuvable.');
}
$company = $employee->getCompany();
if ($application->getApplication()->getCompany() !== $company) {
throw $this->createAccessDeniedException('Cette candidature ne vous appartient pas.');
}
$application->setStatus($status);
$this->entityManager->flush();
$this->addFlash('success', 'Le statut de la candidature a bien été mis à jour.');
return $this->redirectToRoute('app_employee_seeApplications');
}
} }

View File

@ -4,9 +4,7 @@ namespace App\Controller;
use App\Entity\FAQ; use App\Entity\FAQ;
use App\Form\FAQType; use App\Form\FAQType;
use App\Repository\AnnouncementRepository;
use App\Repository\FAQRepository; use App\Repository\FAQRepository;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -17,21 +15,17 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
#[Route('/faq')] #[Route('/faq')]
final class FAQController extends AbstractController final class FAQController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly FaqRepository $faqRepository,
){}
#[Route(name: 'app_faq_index', methods: ['GET'])] #[Route(name: 'app_faq_index', methods: ['GET'])]
public function index(): Response public function index(FAQRepository $fAQRepository): Response
{ {
return $this->render('faq/index.html.twig', [ return $this->render('faq/index.html.twig', [
'faqs' => $this->faqRepository->findAll(), 'faqs' => $fAQRepository->findAll(),
]); ]);
} }
#[Route('/new', name: 'app_faq_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_faq_new', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function new(Request $request,): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$fAQ = new FAQ(); $fAQ = new FAQ();
$form = $this->createForm(FAQType::class, $fAQ); $form = $this->createForm(FAQType::class, $fAQ);
@ -39,8 +33,8 @@ final class FAQController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$fAQ->setUpdateDate(new \DateTime()); $fAQ->setUpdateDate(new \DateTime());
$this->entityManager->persist($fAQ); $entityManager->persist($fAQ);
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER);
} }
@ -61,14 +55,14 @@ final class FAQController extends AbstractController
#[Route('/{id}/edit', name: 'app_faq_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_faq_edit', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function edit(Request $request, FAQ $fAQ,): Response public function edit(Request $request, FAQ $fAQ, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(FAQType::class, $fAQ); $form = $this->createForm(FAQType::class, $fAQ);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$fAQ->setUpdateDate(new \DateTime()); $fAQ->setUpdateDate(new \DateTime());
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER);
} }
@ -81,11 +75,11 @@ final class FAQController extends AbstractController
#[Route('/{id}', name: 'app_faq_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_faq_delete', methods: ['POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function delete(Request $request, FAQ $fAQ,): Response public function delete(Request $request, FAQ $fAQ, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$fAQ->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$fAQ->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($fAQ); $entityManager->remove($fAQ);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_faq_index', [], Response::HTTP_SEE_OTHER);

View File

@ -3,9 +3,7 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\UserApp; use App\Entity\UserApp;
use App\Repository\AnnouncementRepository;
use App\Repository\CompanyRepository; use App\Repository\CompanyRepository;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;

View File

@ -10,37 +10,24 @@ use App\Entity\InternDegree;
use App\Entity\InternSkill; use App\Entity\InternSkill;
use App\Entity\Skill; use App\Entity\Skill;
use App\Form\InternType; use App\Form\InternType;
use App\Repository\AnnouncementRepository;
use App\Repository\DegreeRepository;
use App\Repository\InternApplicationRepository;
use App\Repository\InternDegreeRepository;
use App\Repository\InternRepository; use App\Repository\InternRepository;
use App\Repository\InternSkillRepository;
use App\Repository\SkillRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Constraints\File;
#[Route('/intern')] #[Route('/intern')]
final class InternController extends AbstractController final class InternController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly AnnouncementRepository $announcementRepository,
private readonly InternRepository $internRepository,
private readonly InternApplicationRepository $internApplicationRepository,
private readonly InternDegreeRepository $internDegreeRepository,
private readonly InternSkillRepository $internSkillRepository,
private readonly DegreeRepository $degreeRepository,
private readonly SkillRepository $skillRepository,
){}
#[Route(name: 'app_intern_index', methods: ['GET'])] #[Route(name: 'app_intern_index', methods: ['GET'])]
public function index(): Response public function index(InternRepository $internRepository): Response
{ {
return $this->render('intern/index.html.twig', [ return $this->render('intern/index.html.twig', [
'interns' => $this->internRepository->findAll(), 'interns' => $internRepository->findAll(),
]); ]);
} }
@ -53,13 +40,13 @@ final class InternController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_intern_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_intern_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Intern $intern,): Response public function edit(Request $request, Intern $intern, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(InternType::class, $intern); $form = $this->createForm(InternType::class, $intern);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_intern_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_intern_index', [], Response::HTTP_SEE_OTHER);
} }
@ -70,19 +57,76 @@ final class InternController extends AbstractController
]); ]);
} }
#[Route('/{id}/resume', name: 'app_intern_resume', methods: ['GET', 'POST'])]
public function addResume(Request $request, Intern $intern, EntityManagerInterface $entityManager, #[Autowire('%cv_directory%')] string $cvDirectory): Response
{
// Création d'un formulaire spécifique pour le CV plutôt que d'utiliser InternType entier
$form = $this->createFormBuilder($intern)
->add('resume', FileType::class, [
'label' => 'CV : ',
'mapped' => false, // Ne pas lier directement à l'entité
'constraints' => [
new File([
'maxSize' => '1024k',
'mimeTypes' => [
'application/pdf',
'application/x-pdf',
],
'mimeTypesMessage' => 'Merci de bien vouloir envoyer un fichier PDF valide.',
])
],
])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$cvFile = $form->get('resume')->getData();
if ($cvFile) {
// Génération d'un nom de fichier unique
$newFilename = $intern->getId().'_'.date("d-m-Y").'_'.random_int(0,99999999).'.pdf';
// Déplacement vers le répertoire de stockage
$cvFile->move(
$cvDirectory,
$newFilename
);
if($intern->getResume() !== null){
unlink($cvDirectory.'/'.$intern->getResume());
}
// Mise à jour de l'entité avec le nom du fichier
$intern->setResume($newFilename);
$intern->setResumeName($cvFile->getClientOriginalName()); // Conserver le nom original du fichier
}
$entityManager->flush();
return $this->redirectToRoute('app_profile', [], Response::HTTP_SEE_OTHER);
}
return $this->render('intern/resume.html.twig', [
'intern' => $intern,
'form' => $form->createView(),
]);
}
#[Route('/{id}', name: 'app_intern_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_intern_delete', methods: ['POST'])]
public function delete(Request $request, Intern $intern,): Response public function delete(Request $request, Intern $intern, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$intern->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$intern->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($intern); $entityManager->remove($intern);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_intern_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_intern_index', [], Response::HTTP_SEE_OTHER);
} }
#[Route('/degrees/add', name:'app_intern_add_degrees', methods:['POST'])] #[Route('/degrees/add', name:'app_intern_add_degrees', methods:['POST'])]
public function addDegrees(Request $request): Response public function addDegrees(Request $request, EntityManagerInterface $entityManager): Response
{ {
$intern = $this->getUser(); $intern = $this->getUser();
@ -97,14 +141,17 @@ final class InternController extends AbstractController
return $this->redirectToRoute('app_degree_index'); return $this->redirectToRoute('app_degree_index');
} }
$degreeRepository = $entityManager->getRepository(Degree::class);
$internDegreeRepository = $entityManager->getRepository(InternDegree::class);
foreach ($selectedDegreeIds as $degreeId) { foreach ($selectedDegreeIds as $degreeId) {
$degree = $this->degreeRepository->find($degreeId); $degree = $degreeRepository->find($degreeId);
if (!$degree) { if (!$degree) {
continue; continue;
} }
$existingInternDegree = $this->internDegreeRepository->findOneBy([ $existingInternDegree = $internDegreeRepository->findOneBy([
'intern' => $intern, 'intern' => $intern,
'degree' => $degree 'degree' => $degree
]); ]);
@ -115,11 +162,11 @@ final class InternController extends AbstractController
$internDegree->setDegree($degree); $internDegree->setDegree($degree);
$internDegree->setGraduationDate(new \DateTime()); $internDegree->setGraduationDate(new \DateTime());
$this->entityManager->persist($internDegree); $entityManager->persist($internDegree);
} }
} }
$this->entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'Les diplômes ont été ajoutés avec succès.'); $this->addFlash('success', 'Les diplômes ont été ajoutés avec succès.');
@ -127,17 +174,20 @@ final class InternController extends AbstractController
} }
#[Route('/application/send', name:'app_intern_send_application', methods:['POST'])] #[Route('/application/send', name:'app_intern_send_application', methods:['POST'])]
public function sendApplication(Request $request,): Response public function sendApplication(Request $request, EntityManagerInterface $entityManager): Response
{ {
$intern = $this->getUser(); $intern = $this->getUser();
if (!$intern instanceof Intern) { if (!$intern instanceof Intern) {
throw $this->createAccessDeniedException("Seuls les stagiaires peuvent envoyer des candidatures."); throw $this->createAccessDeniedException("Seuls les stagiaires peuvent envoyer des candidatures.");
} }
$announcementId = $request->request->get('announcement_id'); $announcementRepository = $entityManager->getRepository(Announcement::class);
$announcement = $this->announcementRepository->find($announcementId); $internApplicationRepository = $entityManager->getRepository(InternApplication::class);
$existingInternApplication = $this->internApplicationRepository->findOneBy([ $announcementId = $request->request->get('announcement_id');
$announcement = $announcementRepository->find($announcementId);
$existingInternApplication = $internApplicationRepository->findOneBy([
'intern' => $intern, 'intern' => $intern,
'application' => $announcement 'application' => $announcement
]); ]);
@ -149,9 +199,9 @@ final class InternController extends AbstractController
$internApplication->setApplicationDate(new \DateTime()); $internApplication->setApplicationDate(new \DateTime());
$internApplication->setStatus("En Attente"); $internApplication->setStatus("En Attente");
$this->entityManager->persist($internApplication); $entityManager->persist($internApplication);
} }
$this->entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'La candidature à bien été envoyée.'); $this->addFlash('success', 'La candidature à bien été envoyée.');
@ -160,7 +210,7 @@ final class InternController extends AbstractController
} }
#[Route('/skills/add', name:'app_intern_add_skills', methods:['POST'])] #[Route('/skills/add', name:'app_intern_add_skills', methods:['POST'])]
public function addSkills(Request $request,): Response public function addSkills(Request $request, EntityManagerInterface $entityManager): Response
{ {
$intern = $this->getUser(); $intern = $this->getUser();
@ -175,12 +225,15 @@ final class InternController extends AbstractController
return $this->redirectToRoute('app_skill_index'); return $this->redirectToRoute('app_skill_index');
} }
$skillRepository = $entityManager->getRepository(Skill::class);
$internSkillRepository = $entityManager->getRepository(InternSkill::class);
foreach ($selectedSkillIds as $skillId) { foreach ($selectedSkillIds as $skillId) {
$skill = $this->skillRepository->find($skillId); $skill = $skillRepository->find($skillId);
if (!$skill) continue; if (!$skill) continue;
$existingInternSkill = $this->internSkillRepository->findOneBy([ $existingInternSkill = $internSkillRepository->findOneBy([
'intern' => $intern, 'intern' => $intern,
'skill' => $skill 'skill' => $skill
]); ]);
@ -190,11 +243,11 @@ final class InternController extends AbstractController
$internSkill->setIntern($intern); $internSkill->setIntern($intern);
$internSkill->setSkill($skill); $internSkill->setSkill($skill);
$this->entityManager->persist($internSkill); $entityManager->persist($internSkill);
} }
} }
$this->entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'Les compétences ont été ajoutées avec succès.'); $this->addFlash('success', 'Les compétences ont été ajoutées avec succès.');

View File

@ -5,9 +5,7 @@ namespace App\Controller;
use App\Entity\Announcement; use App\Entity\Announcement;
use App\Entity\Intern; use App\Entity\Intern;
use App\Entity\InternFavorite; use App\Entity\InternFavorite;
use App\Repository\AnnouncementRepository;
use App\Repository\InternFavoriteRepository; use App\Repository\InternFavoriteRepository;
use App\Repository\InternRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
@ -19,69 +17,69 @@ use Symfony\Component\HttpFoundation\Response;
class InternFavoriteController extends AbstractController class InternFavoriteController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly InternFavoriteRepository $internFavoriteRepository,
){}
#[Route('/favorite/toggle/{id}', name: 'toggle_favorite')] #[Route('/favorite/toggle/{id}', name: 'toggle_favorite')]
public function toggleFavorite(Announcement $announcement): RedirectResponse { public function toggleFavorite(
$intern = $this->getUser(); Announcement $announcement,
EntityManagerInterface $em,
InternFavoriteRepository $repo
): RedirectResponse {
$intern = $this->getUser()->getIntern();
$existing = $this->internFavoriteRepository->findOneBy([ $existing = $repo->findOneBy([
'intern' => $intern, 'intern' => $intern,
'announcement' => $announcement 'announcement' => $announcement
]); ]);
if ($existing) { if ($existing) {
$this->entityManager->remove($existing); $em->remove($existing);
} else { } else {
$favorite = new InternFavorite(); $favorite = new InternFavorite();
$favorite->setIntern($intern); $favorite->setIntern($intern);
$favorite->setAnnouncement($announcement); $favorite->setAnnouncement($announcement);
$this->entityManager->persist($favorite); $em->persist($favorite);
} }
$this->entityManager->flush(); $em->flush();
return $this->redirectToRoute('app_announcement_index'); return $this->redirectToRoute('app_announcement_index');
} }
#[Route('/announcement/{id}/favorite/toggle', name: 'app_favorite_toggle', methods: ['POST'])] #[Route('/announcement/{id}/favorite/toggle', name: 'app_favorite_toggle', methods: ['POST'])]
public function toggle(Announcement $announcement,Security $security): RedirectResponse public function toggle(Announcement $announcement, EntityManagerInterface $em, Security $security): RedirectResponse
{ {
$user = $this->getUser(); $user = $security->getUser();
if (!$user instanceof Intern) { if (!$user instanceof Intern) {
throw new AccessDeniedHttpException('Seuls les stagiaires peuvent ajouter aux favoris.'); throw new AccessDeniedHttpException('Seuls les stagiaires peuvent ajouter aux favoris.');
} }
$favorite = $this->entityManager->getRepository(InternFavorite::class)->findOneBy([ $favorite = $em->getRepository(InternFavorite::class)->findOneBy([
'intern' => $user, 'intern' => $user,
'announcement' => $announcement 'announcement' => $announcement
]); ]);
if ($favorite) { if ($favorite) {
$this->entityManager->remove($favorite); $em->remove($favorite);
} else { } else {
$favorite = new InternFavorite(); $favorite = new InternFavorite();
$favorite->setIntern($user); $favorite->setIntern($user);
$favorite->setAnnouncement($announcement); $favorite->setAnnouncement($announcement);
$this->entityManager->persist($favorite); $em->persist($favorite);
} }
$this->entityManager->flush(); $em->flush();
return new RedirectResponse($_SERVER['HTTP_REFERER'] ?? '/'); return new RedirectResponse($_SERVER['HTTP_REFERER'] ?? '/');
} }
#[Route('/announcement/{id}', name: 'app_announcement_show')] #[Route('/announcement/{id}', name: 'app_announcement_show')]
public function show(Announcement $announcement,): Response public function show(Announcement $announcement, InternFavoriteRepository $internFavoriteRepository): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
$isFavorite = false; $isFavorite = false;
if (in_array('ROLE_INTERN', $user->getRoles())) { if (in_array('ROLE_INTERN', $user->getRoles())) {
$favorite = $this->internFavoriteRepository->findOneBy([ $favorite = $internFavoriteRepository->findOneBy([
'announcement' => $announcement, 'announcement' => $announcement,
'intern' => $user, 'intern' => $user,
]); ]);
@ -96,14 +94,12 @@ class InternFavoriteController extends AbstractController
} }
#[Route('/favorite/add/{id}', name: 'app_favorite_add')] #[Route('/favorite/add/{id}', name: 'app_favorite_add')]
public function addFavorite(Announcement $announcement,): Response public function addFavorite(Announcement $announcement, EntityManagerInterface $entityManager): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
if (!$user instanceof Intern) {
throw new AccessDeniedHttpException('Seuls les stagiaires peuvent ajouter aux favoris.');
}
$existingFavorite = $this->entityManager->getRepository(InternFavorite::class)->findOneBy([ // Vérifier si l'intern a déjà ce favori
$existingFavorite = $entityManager->getRepository(InternFavorite::class)->findOneBy([
'announcement' => $announcement, 'announcement' => $announcement,
'intern' => $user, 'intern' => $user,
]); ]);
@ -113,26 +109,26 @@ class InternFavoriteController extends AbstractController
$favorite->setAnnouncement($announcement); $favorite->setAnnouncement($announcement);
$favorite->setIntern($user); $favorite->setIntern($user);
$this->entityManager->persist($favorite); $entityManager->persist($favorite);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_announcement_show', ['id' => $announcement->getId()]); return $this->redirectToRoute('app_announcement_show', ['id' => $announcement->getId()]);
} }
#[Route('/favorite/remove/{id}', name: 'app_favorite_remove')] #[Route('/favorite/remove/{id}', name: 'app_favorite_remove')]
public function removeFavorite(Announcement $announcement,): Response public function removeFavorite(Announcement $announcement, EntityManagerInterface $entityManager): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
$favorite = $this->entityManager->getRepository(InternFavorite::class)->findOneBy([ $favorite = $entityManager->getRepository(InternFavorite::class)->findOneBy([
'announcement' => $announcement, 'announcement' => $announcement,
'intern' => $user, 'intern' => $user,
]); ]);
if ($favorite) { if ($favorite) {
$this->entityManager->remove($favorite); $entityManager->remove($favorite);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_announcement_show', ['id' => $announcement->getId()]); return $this->redirectToRoute('app_announcement_show', ['id' => $announcement->getId()]);

View File

@ -5,33 +5,22 @@ namespace App\Controller;
use App\Entity\Message; use App\Entity\Message;
use App\Entity\UserApp; use App\Entity\UserApp;
use App\Form\MessageType; use App\Form\MessageType;
use App\Repository\AnnouncementRepository;
use App\Repository\InternSkillRepository;
use App\Repository\MessageRepository; use App\Repository\MessageRepository;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
#[Route('/message')] #[Route('/message')]
final class MessageController extends AbstractController final class MessageController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly MessageRepository $messageRepository,
private readonly UserRepository $userRepository,
){}
#[Route(name: 'app_message_index', methods: ['GET'])] #[Route(name: 'app_message_index', methods: ['GET'])]
public function index(): Response public function index(MessageRepository $messageRepository): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
if (!$user instanceof UserApp) { $messages = $messageRepository->findLatestMessagesByUser($user);
throw new AccessDeniedHttpException("erreur");
}
$messages = $this->messageRepository->findLatestMessagesByUser($user);
return $this->render('message/index.html.twig', [ return $this->render('message/index.html.twig', [
'messages' => $messages, 'messages' => $messages,
@ -39,12 +28,12 @@ final class MessageController extends AbstractController
} }
#[Route('/conversation/{id}', name: 'app_message_conversation', methods: ['GET'])] #[Route('/conversation/{id}', name: 'app_message_conversation', methods: ['GET'])]
public function conversation(Message $message,): Response public function conversation(Message $message, MessageRepository $messageRepository): Response
{ {
$user = $this->getUser(); $user = $this->getUser();
$otherUser = $message->getSender() === $user ? $message->getReceiver() : $message->getSender(); $otherUser = $message->getSender() === $user ? $message->getReceiver() : $message->getSender();
$conversation = $this->messageRepository->findByConversation($user, $otherUser); $conversation = $messageRepository->findByConversation($user, $otherUser);
return $this->render('message/conversation.html.twig', [ return $this->render('message/conversation.html.twig', [
'conversation' => $conversation, 'conversation' => $conversation,
@ -55,12 +44,12 @@ final class MessageController extends AbstractController
#[Route('/new/{receiverId}', name: 'app_message_new', methods: ['GET', 'POST'])] #[Route('/new/{receiverId}', name: 'app_message_new', methods: ['GET', 'POST'])]
public function new(Request $request, ?int $receiverId = null,): Response public function new(Request $request, EntityManagerInterface $entityManager, ?int $receiverId = null, UserRepository $userRepository): Response
{ {
$message = new Message(); $message = new Message();
if ($receiverId) { if ($receiverId) {
$receiver = $this->userRepository->find($receiverId); $receiver = $userRepository->find($receiverId);
if ($receiver) { if ($receiver) {
$message->setReceiver($receiver); $message->setReceiver($receiver);
} }
@ -73,8 +62,8 @@ final class MessageController extends AbstractController
$message->setSendingDate(new \DateTime()); $message->setSendingDate(new \DateTime());
$message->setSender($this->getUser()); $message->setSender($this->getUser());
$this->entityManager->persist($message); $entityManager->persist($message);
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_message_index'); return $this->redirectToRoute('app_message_index');
} }
@ -93,14 +82,14 @@ final class MessageController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_message_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_message_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Message $message,): Response public function edit(Request $request, Message $message, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(MessageType::class, $message); $form = $this->createForm(MessageType::class, $message);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$message->setSendingDate(new \DateTime()); $message->setSendingDate(new \DateTime());
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER);
} }
@ -112,11 +101,11 @@ final class MessageController extends AbstractController
} }
#[Route('/{id}', name: 'app_message_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_message_delete', methods: ['POST'])]
public function delete(Request $request, Message $message,): Response public function delete(Request $request, Message $message, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$message->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$message->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($message); $entityManager->remove($message);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_message_index', [], Response::HTTP_SEE_OTHER);

View File

@ -7,34 +7,31 @@ use App\Entity\Intern;
use App\Entity\InternApplication; use App\Entity\InternApplication;
use App\Entity\UserApp; use App\Entity\UserApp;
use App\Form\UserAppType; use App\Form\UserAppType;
use App\Repository\InternApplicationRepository;
use App\Repository\SkillRepository; use App\Repository\SkillRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
class ProfileController extends AbstractController class ProfileController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly InternApplicationRepository $internApplicationRepository,
){}
#[Route('/profile', name: 'app_profile')] #[Route('/profile', name: 'app_profile')]
public function profile(): Response public function profile(EntityManagerInterface $entityManager): Response
{ {
// Charger l'utilisateur connecté
$user = $this->getUser(); $user = $this->getUser();
// Vérifiez les rôles si nécessaire
if (!$user) { if (!$user) {
throw $this->createAccessDeniedException('Vous devez être connecté pour accéder à cette page.'); throw $this->createAccessDeniedException('Vous devez être connecté pour accéder à cette page.');
} }
if ($user instanceof Intern) if ($user instanceof Intern)
{ {
$internApplicationRepository = $entityManager->getRepository(InternApplication::class);
$internApplications = $this->internApplicationRepository->findBy([ $internApplications = $internApplicationRepository->findBy([
'intern' => $user, 'intern' => $user,
]); ]);
@ -51,20 +48,13 @@ class ProfileController extends AbstractController
} }
#[Route('profile/{id}/edit', name: 'app_profile_edit', methods: ['GET', 'POST'])] #[Route('profile/{id}/edit', name: 'app_profile_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, UserApp $userApp, UserPasswordHasherInterface $passwordHasher): Response public function edit(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(UserAppType::class, $userApp); $form = $this->createForm(UserAppType::class, $userApp);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$plainPassword = $form->get('password')->getData(); $entityManager->flush();
if (!empty($plainPassword)) {
$hashedPassword = $passwordHasher->hashPassword($userApp, $plainPassword);
$userApp->setPassword($hashedPassword);
}
$this->entityManager->flush();
return $this->redirectToRoute('app_profile', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_profile', [], Response::HTTP_SEE_OTHER);
} }
@ -75,17 +65,17 @@ class ProfileController extends AbstractController
]); ]);
} }
#[Route('/profile/visit/{id}', name: 'app_profile_visit')] #[Route('/profile/{id}/visit', name: 'app_profile_visit')]
public function visitProfile(int $id): Response public function visitProfile(EntityManagerInterface $entityManager, int $id): Response
{ {
$candidat = $this->entityManager->getRepository(Intern::class)->find($id); $user = $entityManager->getRepository(Intern::class)->find($id);
if (!$candidat) { if (!$user) {
throw $this->createNotFoundException('Utilisateur non trouvé.'); throw $this->createNotFoundException('Utilisateur non trouvé.');
} }
return $this->render('profile/visit.html.twig', [ return $this->render('profile/index.html.twig', [
'candidat' => $candidat, 'user' => $user,
]); ]);
} }

View File

@ -6,25 +6,19 @@ use App\Entity\Employee;
use App\Entity\Intern; use App\Entity\Intern;
use App\Entity\UserApp; use App\Entity\UserApp;
use App\Form\RegistrationFormType; use App\Form\RegistrationFormType;
use App\Repository\InternApplicationRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use App\Entity\Company;
#[Route('/register', name: 'app_register')] #[Route('/register', name: 'app_register')]
class RegistrationController extends AbstractController class RegistrationController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
){}
#[Route('/', name: '_intern')] #[Route('/', name: '_intern')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, Security $security): Response public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, Security $security, EntityManagerInterface $entityManager): Response
{ {
$user = new Intern(); $user = new Intern();
$form = $this->createForm(RegistrationFormType::class, $user); $form = $this->createForm(RegistrationFormType::class, $user);
@ -38,52 +32,44 @@ class RegistrationController extends AbstractController
// encode the plain password // encode the plain password
$user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword)); $user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword));
$this->entityManager->persist($user); $entityManager->persist($user);
$this->entityManager->flush(); $entityManager->flush();
// do anything else you need here, like send an email
return $security->login($user, 'form_login', 'main'); return $security->login($user, 'form_login', 'main');
} }
return $this->render('registration/register.html.twig', [ return $this->render('registration/register.html.twig', [
'registrationForm' => $form, 'registrationForm' => $form,
'employee' => False,
]); ]);
} }
#[Route('/employee', name: '_employee')] #[Route('/employee', name: '_employee')]
public function registerEmployee(Request $request, UserPasswordHasherInterface $userPasswordHasher, Security $security): Response public function registerEmployee(Request $request, UserPasswordHasherInterface $userPasswordHasher, Security $security, EntityManagerInterface $entityManager): Response
{ {
$user = new Employee(); $user = new Employee();
$form = $this->createForm(RegistrationFormType::class, $user) $form = $this->createForm(RegistrationFormType::class, $user);
->add('company', EntityType::class, [
'class' => Company::class,
'choice_label' => 'name',
'placeholder' => 'Sélectionnez une entreprise',
'label' => 'Entreprise',
]);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
/** @var string $plainPassword */ /** @var string $plainPassword */
$plainPassword = $form->get('plainPassword')->getData(); $plainPassword = $form->get('plainPassword')->getData();
$company = $form->get('company')->getData();
$user->setCompany($company);
$user->setRoles(['ROLE_EMPLOYEE']); $user->setRoles(['ROLE_EMPLOYEE']);
// Encoder le mot de passe // encode the plain password
$user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword)); $user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword));
$this->entityManager->persist($user); $entityManager->persist($user);
$this->entityManager->flush(); $entityManager->flush();
// do anything else you need here, like send an email
return $security->login($user, 'form_login', 'main'); return $security->login($user, 'form_login', 'main');
} }
return $this->render('registration/register.html.twig', [ return $this->render('registration/register.html.twig', [
'registrationForm' => $form, 'registrationForm' => $form,
'employee' => True,
]); ]);
} }
} }

View File

@ -2,9 +2,7 @@
namespace App\Controller; namespace App\Controller;
use App\Repository\InternApplicationRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

View File

@ -4,8 +4,6 @@ namespace App\Controller;
use App\Entity\Skill; use App\Entity\Skill;
use App\Form\SkillType; use App\Form\SkillType;
use App\Repository\AnnouncementRepository;
use App\Repository\InternApplicationRepository;
use App\Repository\SkillRepository; use App\Repository\SkillRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -17,29 +15,25 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
#[Route('/skill')] #[Route('/skill')]
final class SkillController extends AbstractController final class SkillController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly AnnouncementRepository $skillRepository,
){}
#[Route(name: 'app_skill_index', methods: ['GET'])] #[Route(name: 'app_skill_index', methods: ['GET'])]
public function index(): Response public function index(SkillRepository $skillRepository): Response
{ {
return $this->render('skill/index.html.twig', [ return $this->render('skill/index.html.twig', [
'skills' => $this->skillRepository->findAll(), 'skills' => $skillRepository->findAll(),
]); ]);
} }
#[Route('/new', name: 'app_skill_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_skill_new', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function new(Request $request,): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$skill = new Skill(); $skill = new Skill();
$form = $this->createForm(SkillType::class, $skill); $form = $this->createForm(SkillType::class, $skill);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($skill); $entityManager->persist($skill);
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);
} }
@ -60,13 +54,13 @@ final class SkillController extends AbstractController
#[Route('/{id}/edit', name: 'app_skill_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_skill_edit', methods: ['GET', 'POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function edit(Request $request, Skill $skill,): Response public function edit(Request $request, Skill $skill, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(SkillType::class, $skill); $form = $this->createForm(SkillType::class, $skill);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);
} }
@ -79,11 +73,11 @@ final class SkillController extends AbstractController
#[Route('/{id}', name: 'app_skill_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_skill_delete', methods: ['POST'])]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function delete(Request $request, Skill $skill,): Response public function delete(Request $request, Skill $skill, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$skill->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$skill->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($skill); $entityManager->remove($skill);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_skill_index', [], Response::HTTP_SEE_OTHER);

View File

@ -4,7 +4,6 @@ namespace App\Controller;
use App\Entity\UserApp; use App\Entity\UserApp;
use App\Form\UserAppType; use App\Form\UserAppType;
use App\Repository\AnnouncementRepository;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -15,15 +14,11 @@ use Symfony\Component\Routing\Attribute\Route;
#[Route('/user')] #[Route('/user')]
final class UserAppController extends AbstractController final class UserAppController extends AbstractController
{ {
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly UserRepository $userRepository,
){}
#[Route(name: 'app_user_index', methods: ['GET'])] #[Route(name: 'app_user_index', methods: ['GET'])]
public function index(): Response public function index(UserRepository $userRepository): Response
{ {
return $this->render('user_app/index.html.twig', [ return $this->render('user_app/index.html.twig', [
'user_apps' => $this->userRepository->findAll(), 'user_apps' => $userRepository->findAll(),
]); ]);
} }
@ -36,13 +31,13 @@ final class UserAppController extends AbstractController
} }
#[Route('/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_user_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, UserApp $userApp,): Response public function edit(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{ {
$form = $this->createForm(UserAppType::class, $userApp); $form = $this->createForm(UserAppType::class, $userApp);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
} }
@ -54,11 +49,11 @@ final class UserAppController extends AbstractController
} }
#[Route('/{id}', name: 'app_user_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_user_delete', methods: ['POST'])]
public function delete(Request $request, UserApp $userApp,): Response public function delete(Request $request, UserApp $userApp, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$userApp->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$userApp->getId(), $request->getPayload()->getString('_token'))) {
$this->entityManager->remove($userApp); $entityManager->remove($userApp);
$this->entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);

View File

@ -7,7 +7,6 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CompanyRepository::class)] #[ORM\Entity(repositoryClass: CompanyRepository::class)]
class Company class Company
{ {

View File

@ -7,18 +7,20 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use App\Entity\Company;
#[ORM\Entity(repositoryClass: InternRepository::class)] #[ORM\Entity(repositoryClass: InternRepository::class)]
class Intern extends UserApp class Intern extends UserApp
{ {
#[ORM\Column(type: Types::TEXT,nullable: true)] #[ORM\Column(type: Types::TEXT, length: 255, nullable: true)]
private ?string $coverLetter = null; private ?string $coverLetter = null;
#[ORM\Column(length: 255,nullable: true)] #[ORM\Column(type: Types::TEXT, length: 255, nullable: true)]
private ?string $resume = null; private ?string $resume = null;
#[ORM\Column(type: Types::TEXT, length: 255, nullable: true)]
private ?string $resumeName = null;
/** /**
* @var Collection<int, InternDegree> * @var Collection<int, InternDegree>
*/ */
@ -75,6 +77,18 @@ class Intern extends UserApp
return $this; return $this;
} }
public function getResumeName(): ?string
{
return $this->resumeName;
}
public function setResumeName(string $resumeName): static
{
$this->resumeName = $resumeName;
return $this;
}
/** /**
* @return Collection<int, InternDegree> * @return Collection<int, InternDegree>
*/ */

View File

@ -10,7 +10,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
#[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: 'userApp')] #[ORM\Table(name: 'userApp')]
#[ORM\InheritanceType('SINGLE_TABLE')] #[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'DISCRIMINATOR', type: 'string')] #[ORM\DiscriminatorColumn(name: 'DISCRIMINATOR', type: 'string')]
#[ORM\DiscriminatorMap(['employee' => Employee::class, 'intern' => Intern::class])] #[ORM\DiscriminatorMap(['employee' => Employee::class, 'intern' => Intern::class])]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_NICKNAME', fields: ['nickname'])] #[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_NICKNAME', fields: ['nickname'])]
@ -186,7 +186,6 @@ class UserApp implements UserInterface, PasswordAuthenticatedUserInterface
return $this; return $this;
} }
} }

View File

@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\Announcement; use App\Entity\Announcement;
use App\Entity\Company; use App\Entity\Company;
use App\Entity\Status;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -17,6 +18,10 @@ class AnnouncementType extends AbstractType
$builder $builder
->add('title') ->add('title')
->add('description') ->add('description')
->add('company', EntityType::class, [
'class' => Company::class,
'choice_label' => 'name',
])
->add('date', TextType::class, [ ->add('date', TextType::class, [
'label' => 'Date de stage', 'label' => 'Date de stage',
'required' => true, 'required' => true,

View File

@ -4,8 +4,11 @@ namespace App\Form;
use App\Entity\Intern; use App\Entity\Intern;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\File;
class InternType extends AbstractType class InternType extends AbstractType
{ {
@ -20,7 +23,9 @@ class InternType extends AbstractType
->add('tel') ->add('tel')
->add('address') ->add('address')
->add('mail') ->add('mail')
->add('coverLetter') ->add('coverLetter', TextareaType::class, [
'required' => false,
])
->add('resume') ->add('resume')
; ;
} }

View File

@ -15,19 +15,12 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use App\Entity\Company;
use App\Entity\Intern;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class RegistrationFormType extends AbstractType class RegistrationFormType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('nickname', TextType::class, [ ->add('nickname', TextType::class, [
'label' => 'Utilisateur : ', 'label' => 'Utilisateur : ',
]) ])
@ -52,7 +45,10 @@ class RegistrationFormType extends AbstractType
new NotBlank(), new NotBlank(),
] ]
]) ])
//
->add('plainPassword', PasswordType::class, [ ->add('plainPassword', PasswordType::class, [
// instead of being set onto the object directly,
// this is read and encoded in the controller
'mapped' => false, 'mapped' => false,
'attr' => ['autocomplete' => 'new-password'], 'attr' => ['autocomplete' => 'new-password'],
'constraints' => [ 'constraints' => [
@ -62,10 +58,12 @@ class RegistrationFormType extends AbstractType
new Length([ new Length([
'min' => 6, 'min' => 6,
'minMessage' => 'Votre mot de passe doit avoir au moins {{ limit }} caractères', 'minMessage' => 'Votre mot de passe doit avoir au moins {{ limit }} caractères',
// max length allowed by Symfony for security reasons
'max' => 4096, 'max' => 4096,
]), ]),
], ],
]); ])
;
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void

View File

@ -4,7 +4,6 @@ namespace App\Form;
use App\Entity\UserApp; use App\Entity\UserApp;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
@ -14,19 +13,12 @@ class UserAppType extends AbstractType
{ {
$builder $builder
->add('nickname') ->add('nickname')
->add('password')
->add('firstName') ->add('firstName')
->add('lastName') ->add('lastName')
->add('tel') ->add('tel')
->add('address') ->add('address')
->add('mail') ->add('mail')
->add('password', PasswordType::class, [
'mapped' => false,
'required' => false,
'attr' => [
'autocomplete' => 'new-password'
],
'label' => 'Nouveau mot de passe',
])
; ;
} }

View File

@ -43,17 +43,15 @@
<span class="text-green-500 font-semibold">Validée</span> <span class="text-green-500 font-semibold">Validée</span>
{% endif %} {% endif %}
{% if 'ROLE_INTERN' in app.user.roles %} <form method="post" action="{{ path('app_favorite_toggle', {id: announcement.id}) }}">
<form method="post" action="{{ path('app_favorite_toggle', {id: announcement.id}) }}"> <button type="submit" class="text-xl">
<button type="submit" class="text-xl"> {% if announcement.id in favorites %}
{% if announcement.id in favorites %}
{% else %}
{% else %}
{% endif %}
{% endif %} </button>
</button> </form>
</form>
{% endif %}
</div> </div>
<h2 class="text-3xl font-semibold mb-2">{{ announcement.title }}</h2> <h2 class="text-3xl font-semibold mb-2">{{ announcement.title }}</h2>

View File

@ -4,7 +4,7 @@
{% block body %} {% block body %}
<div class="container mx-auto p-6"> <div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Créer une Annonce pour {{ company.name }}</h1> <h1 class="text-3xl font-bold mb-4">Créer une Annonce</h1>
{{ form_start(form) }} {{ form_start(form) }}
<div class="mb-4"> <div class="mb-4">
@ -19,6 +19,10 @@
{{ form_label(form.date) }} {{ form_label(form.date) }}
{{ form_widget(form.date, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }} {{ form_widget(form.date, {'attr': {'class': 'form-input w-full p-2 rounded border'}}) }}
</div> </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"> <button type="submit" class="bg-teal-500 text-white px-4 py-2 rounded">
Créer l'annonce Créer l'annonce
</button> </button>

View File

@ -59,16 +59,6 @@
<i class="fas fa-paper-plane"></i> Candidater à cette offre <i class="fas fa-paper-plane"></i> Candidater à cette offre
</button> </button>
</form> </form>
<!-- Vérifier si c'est un favori -->
<form method="post" action="{{ path(isFavorite ? 'app_favorite_remove' : 'app_favorite_add', {id: announcement.id}) }}">
<button type="submit" class="text-yellow-500">
{% if isFavorite %}
⭐ Retirer des favoris
{% else %}
☆ Ajouter aux favoris
{% endif %}
</button>
</form>
{% endif %} {% endif %}
{% if 'ROLE_ADMIN' in app.user.roles %} {% if 'ROLE_ADMIN' in app.user.roles %}
@ -88,7 +78,18 @@
</form> </form>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
<!-- Vérifier si c'est un favori -->
<form method="post" action="{{ path(isFavorite ? 'app_favorite_remove' : 'app_favorite_add', {id: announcement.id}) }}">
<button type="submit" class="text-yellow-500">
{% if isFavorite %}
⭐ Retirer des favoris
{% else %}
☆ Ajouter aux favoris
{% endif %}
</button>
</form>
</div> </div>
<!-- Bouton de retour à la liste --> <!-- Bouton de retour à la liste -->

View File

@ -56,23 +56,11 @@
</table> </table>
</div> </div>
{% if 'ROLE_INTERN' in app.user.roles %}
<div class="mt-4">
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-full">
<i class="fas fa-check-circle"></i> Valider la sélection
</button>
</div>
</form>
{% endif %}
{% if 'ROLE_ADMIN' in app.user.roles %}
<!-- Lien pour ajouter un nouveau diplôme --> <!-- Lien pour ajouter un nouveau diplôme -->
<div class="mt-4"> <div class="mt-4">
<a href="{{ path('app_degree_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 <a href="{{ path('app_degree_new') }}" class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
rounded-full">
<i class="fas fa-plus-circle"></i> Ajouter un nouveau diplôme <i class="fas fa-plus-circle"></i> Ajouter un nouveau diplôme
</a> </a>
</div> </div>
{% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -3,41 +3,22 @@
{% block title %}Liste des Candidatures{% endblock %} {% block title %}Liste des Candidatures{% endblock %}
{% block body %} {% block body %}
<div class="max-w-2xl mx-auto mt-8"> <h2 class="text-2xl font-bold mb-6">Candidatures reçues</h2>
<h2 class="text-3xl font-semibold text-center mb-8 text-gray-800">Candidatures reçues</h2>
{% for app in applications %} {% for app in applications %}
<div class="border border-gray-200 rounded-2xl p-6 shadow-md bg-white space-y-2"> <div class="border border-gray-300 rounded-lg p-4 mb-4 shadow-sm bg-white">
<p><span class="font-semibold text-gray-700">Annonce :</span> {{ app.application.title }}</p> <p><strong>Annonce :</strong> {{ app.application.title }}</p>
<p><span class="font-semibold text-gray-700">Candidat :</span> {{ app.intern.firstName }} {{ app.intern.lastName }}</p> <p><strong>Candidat :</strong> {{ app.intern.firstName }} {{ app.intern.lastName }}</p>
<p><span class="font-semibold text-gray-700">Date :</span> {{ app.applicationDate|date('d/m/Y') }}</p> <p><strong>Date :</strong> {{ app.applicationDate|date('d/m/Y') }}</p>
<p><span class="font-semibold text-gray-700">Statut :</span> {{ app.status|capitalize }}</p> <p><strong>Statut :</strong> {{ app.status }}</p>
<a href="{{ path('app_profile_visit', { id: app.intern.id }) }}" <a href="{{ path('app_profile_visit', { id: app.intern.id }) }}"
class="inline-block mt-3 bg-teal-500 hover:bg-teal-600 text-white px-4 py-2 rounded shadow"> class="inline-block mt-2 bg-teal-500 hover:bg-teal-600 text-white px-4 py-2 rounded">
Voir le profil du candidat Voir le profil du candidat
</a> </a>
{% if app.status == 'En Attente' %}
<div class="flex justify-end gap-3 mt-4">
<form method="post" action="{{ path('app_employee_update_application_status',
{id: app.id, status: 'Acceptée'}) }}">
<button type="submit" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded shadow">
Accepter
</button>
</form>
<form method="post" action="{{ path('app_employee_update_application_status',
{id: app.id, status: 'Refusée'}) }}">
<button type="submit" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded shadow">
Refuser
</button>
</form>
</div>
{% endif %}
</div>
{% else %}
<p class="text-center text-gray-600">Aucune candidature pour le moment.</p>
{% endfor %}
</div> </div>
{% else %}
<p>Aucune candidature pour le moment.</p>
{% endfor %}
{% endblock %} {% endblock %}

View File

@ -1,55 +1,25 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block title %}Liste des FAQs{% endblock %} {% block title %}FAQ{% endblock %}
{% block body %} {% block body %}
<div class="container mx-auto p-6"> <div class="container mx-auto p-6">
<h1 class="text-3xl font-bold mb-4">Liste des FAQs</h1> <h1 class="text-3xl font-bold mb-4">FAQ</h1>
<div class="overflow-x-auto bg-white shadow-lg rounded-lg"> <div class="flex flex-col gap-4">
<table class="min-w-full table-auto"> {% for faq in faqs %}
<thead> <div>
<tr class="bg-gray-800 text-white"> <h2 class="font-bold text-4xl">Question : {{ faq.question }}</h2>
<th class="px-4 py-2 text-left">Question</th> <p class="italic text-gray-700">Dernière modification : {{ faq.updateDate|date("d-m-y") }}</p>
<th class="px-4 py-2 text-left">Réponse</th> <p class="text-2xl ml-10">Réponse : {{ faq.answer }}</p>
<th class="px-4 py-2 text-left">Denrnière modif</th> </div>
<th class="px-4 py-2 text-left">Actions</th> <hr class="border-black"/>
</tr> {% endfor %}
</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>
<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>
<div class="mt-4"> <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"> <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 <i class="fas fa-plus-circle"></i> Ajouter une FAQ / Poser une question
</a> </a>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,23 @@
{% extends 'base.html.twig' %}
{% block title %}Resume{% endblock %}
{% block body %}
<div class="container mx-auto p-6">
<h1 class="text-4xl font-semibold text-gray-800 mb-6">Ajouter / Modifier le CV</h1>
<div class="bg-white shadow-md rounded-lg p-6">
{{ form_start(form, {'attr': {'enctype': 'multipart/form-data'}}) }}
<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">
Enregistrer
</button>
{{ form_end(form) }}
</div>
</div>
{% endblock %}

View File

@ -16,11 +16,7 @@
{{ form_row(form.tel, {'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.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.mail, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
{{ form_row(form.password, { {{ form_row(form.password, {'attr': {'class': 'w-full p-3 border rounded-md'}}) }}
'attr': {'class': 'w-full p-3 border rounded-md'},
'label': 'Mot de passe (laissez vide pour ne pas changer)',
}) }}
</div> </div>
<div class="mt-6"> <div class="mt-6">
{{ form_widget(form) }} {{ form_widget(form) }}

View File

@ -8,9 +8,9 @@
<p class="text-gray-600">Téléphone : {{ app.user.tel }}</p> <p class="text-gray-600">Téléphone : {{ app.user.tel }}</p>
<p class="text-gray-600">Email : {{ app.user.mail }}</p> <p class="text-gray-600">Email : {{ app.user.mail }}</p>
<a href="{{ path('app_employee_seeApplications') }}"
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded">
href="{{ path('app_employee_seeApplications') }}"> Voir les candidatures reçues Voir les candidatures reçues
</a> </a>

View File

@ -2,11 +2,30 @@
<h2 class="text-xl font-semibold mb-4">Bonjour {{ app.user.nickname }}</h2> <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> <p class="text-gray-700">Vous êtes à la recherche d'un stage.</p>
<br> <br>
<p class="text-gray-600">Nom : {{ app.user.firstName }}</p>
<p class="text-gray-600">Prénom : {{ app.user.lastName }}</p> <div class="flex justify-around">
<p class="text-gray-600">Adresse : {{ app.user.address }}</p> <div class="flex flex-col gap-5">
<p class="text-gray-600">Téléphone : {{ app.user.tel }}</p> <p class="text-gray-600">Nom : {{ app.user.firstName }}</p>
<p class="text-gray-600">Email : {{ app.user.mail }}</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>
</div>
{% if app.user.resume != "" %}
<div>
<iframe height="575px" width="400px" src={{ 'cv/' ~ app.user.resume }}></iframe>
{% if app.user.resumeName != "" %}
<p class="text-gray-600 italic">Nom du fichier : {{ app.user.resumeName }}</p>
{% endif %}
</div>
{% endif %}
</div>
<br>
<a class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"
href="{{ path('app_intern_resume',{id: app.user.id}) }}"> Ajouter / Modifier le CV
</a>
<h3 class="text-lg font-semibold mt-6">Vos diplômes :</h3> <h3 class="text-lg font-semibold mt-6">Vos diplômes :</h3>
<ul class="list-disc list-inside text-gray-800"> <ul class="list-disc list-inside text-gray-800">

View File

@ -7,18 +7,18 @@
<h2 class="text-2xl font-bold mb-4">Profil du candidat</h2> <h2 class="text-2xl font-bold mb-4">Profil du candidat</h2>
<div class="mb-4"> <div class="mb-4">
<p><strong>Nom :</strong> {{ candidat.lastName }}</p> <p><strong>Nom :</strong> {{ user.lastName }}</p>
<p><strong>Prénom :</strong> {{ candidat.firstName }}</p> <p><strong>Prénom :</strong> {{ user.firstName }}</p>
<p><strong>Email :</strong> {{ candidat.mail }}</p> <p><strong>Email :</strong> {{ user.mail }}</p>
<p><strong>Téléphone :</strong> {{ candidat.tel }}</p> <p><strong>Téléphone :</strong> {{ user.tel }}</p>
<p><strong>Adresse :</strong> {{ candidat.address }}</p> <p><strong>Adresse :</strong> {{ user.address }}</p>
</div> </div>
<div class="mb-4"> <div class="mb-4">
<h3 class="text-xl font-semibold">Diplômes</h3> <h3 class="text-xl font-semibold">Diplômes</h3>
<ul class="list-disc list-inside text-gray-800 mt-2"> <ul class="list-disc list-inside text-gray-800 mt-2">
{% if candidat.degrees|length > 0 %} {% if user.degrees|length > 0 %}
{% for deg in candidat.degrees %} {% for deg in user.degrees %}
<li> <li>
{{ deg.degree.label }} — Obtenu le {{ deg.graduationDate|date('d/m/Y') }} {{ deg.degree.label }} — Obtenu le {{ deg.graduationDate|date('d/m/Y') }}
</li> </li>
@ -32,9 +32,9 @@
<div class="mb-4"> <div class="mb-4">
<h3 class="text-xl font-semibold">Compétences</h3> <h3 class="text-xl font-semibold">Compétences</h3>
<ul class="list-disc list-inside text-gray-800 mt-2"> <ul class="list-disc list-inside text-gray-800 mt-2">
{% if candidat.skills|length > 0 %} {% if user.skills|length > 0 %}
{% for sk in candidat.skills %} {% for skill in user.skills %}
<li>{{ sk.skill.label }}</li> <li>{{ skill.label }}</li>
{% endfor %} {% endfor %}
{% else %} {% else %}
<p class="text-gray-500 mt-2">Aucune compétence renseignée.</p> <p class="text-gray-500 mt-2">Aucune compétence renseignée.</p>
@ -43,9 +43,9 @@
</div> </div>
<div class="mt-6"> <div class="mt-6">
<a href="{{ path('app_employee_seeApplications') }}" <a href="{{ path('app_index') }}"
class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full"> class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-4 rounded-full">
Retour à la liste des candidatures Retour à l'accueil
</a> </a>
</div> </div>
</div> </div>

View File

@ -36,15 +36,6 @@
{{ form_errors(registrationForm.mail) }} {{ form_errors(registrationForm.mail) }}
</div> </div>
{% if employee %}
<div class="mb-4">
{{ form_label(registrationForm.company, 'Sélectionnez une entreprise', {'label_attr': {'class': 'block text-gray-700 mb-2'}}) }}
{{ form_widget(registrationForm.company, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}
{{ form_errors(registrationForm.company) }}
</div>
{% endif %}
<!-- Mot de passe -->
<div class="mb-4"> <div class="mb-4">
{{ form_label(registrationForm.plainPassword, 'Mot de passe', {'label_attr': {'class': 'block text-gray-700 mb-2'}}) }} {{ form_label(registrationForm.plainPassword, 'Mot de passe', {'label_attr': {'class': 'block text-gray-700 mb-2'}}) }}
{{ form_widget(registrationForm.plainPassword, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }} {{ form_widget(registrationForm.plainPassword, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500'}}) }}