From a9f418d51f7bf522b611aa37cdbc06e85c32cb39 Mon Sep 17 00:00:00 2001 From: Baptiste Buvron Date: Thu, 22 Jun 2023 12:17:40 +0200 Subject: [PATCH] Fix: - un recruteur peut modifier et supprimer une offre - fix header - ajout fake data --- app/controllers/AdminController.ts | 90 +++++++++++++++++---- app/controllers/OfferController.ts | 3 +- app/controllers/RecruteurController.ts | 28 +++++-- app/routes/RecruterRouter.ts | 8 +- app/table.sql | 105 +++++++++++++++++++++++-- app/views/admin/modifierOffre.ejs | 15 +++- app/views/admin/offre.ejs | 27 ++++--- app/views/offre/offre.ejs | 34 +++++++- app/views/partials/adminHeader.ejs | 2 +- app/views/partials/header.ejs | 9 ++- app/views/partials/recruteurHeader.ejs | 2 +- 11 files changed, 269 insertions(+), 54 deletions(-) diff --git a/app/controllers/AdminController.ts b/app/controllers/AdminController.ts index f064ec6..ab64cd1 100644 --- a/app/controllers/AdminController.ts +++ b/app/controllers/AdminController.ts @@ -14,15 +14,25 @@ export class AdminController { static index(req: express.Request, res: express.Response) { FicheDePosteRepository.getDistinctRegion().then((regions: string[]) => { OfferRepository.getAll().then((offers: OffreDePoste[]) => { - res.render("admin/index", {title: "Home", offers: offers, regions: regions, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/index", { + title: "Home", + offers: offers, + regions: regions, + userLogged: loggedInNoRedirection(req, res) + }); }); }); } static utilisateurs(req: express.Request, res: express.Response) { UserRepository.getAll().then((users: User[]) => { - OrganisationRepository.getAll().then((organisations : Organisation[]) => { - res.render("admin/utilisateurs", { title: "Utilisateurs", organisations: organisations, users, userLogged: loggedInNoRedirection(req, res)}); + OrganisationRepository.getAll().then((organisations: Organisation[]) => { + res.render("admin/utilisateurs", { + title: "Utilisateurs", + organisations: organisations, + users, + userLogged: loggedInNoRedirection(req, res) + }); }); }); } @@ -30,7 +40,11 @@ export class AdminController { static utilisateur(req: express.Request, res: express.Response) { let email = req.params.email; UserRepository.getById(email).then((user: User) => { - res.render("admin/utilisateur", {title: "Utilisateur", user: user, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/utilisateur", { + title: "Utilisateur", + user: user, + userLogged: loggedInNoRedirection(req, res) + }); }) } @@ -61,9 +75,14 @@ export class AdminController { console.log(err); }); UserRepository.getById(req.body.email).then((user: User) => { - res.render("admin/utilisateur", {title: "Utilisateur", user: user, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/utilisateur", { + title: "Utilisateur", + user: user, + alerts: alerts, + userLogged: loggedInNoRedirection(req, res) + }); }) - }else{ + } else { let email = req.params.email; UserRepository.getById(email).then((user: User) => { res.render("admin/modifierUtilisateur", { @@ -90,15 +109,26 @@ export class AdminController { }); UserRepository.getAll().then((users: User[]) => { - res.render("admin/utilisateurs", { title: "Utilisateurs", users, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/utilisateurs", { + title: "Utilisateurs", + users, + alerts: alerts, + userLogged: loggedInNoRedirection(req, res) + }); }); } static demandes(req: express.Request, res: express.Response) { UserRepository.getNewRecruiterDemand().then((users: User[]) => { UserRepository.getOldRecruiterDemand().then((oldUsers: User[]) => { - OrganisationRepository.getAll().then((organisations : Organisation[]) => { - res.render("admin/demandes", {title: "Demandes", users: users, organisations: organisations, oldUsers: oldUsers, userLogged: loggedInNoRedirection(req, res)}); + OrganisationRepository.getAll().then((organisations: Organisation[]) => { + res.render("admin/demandes", { + title: "Demandes", + users: users, + organisations: organisations, + oldUsers: oldUsers, + userLogged: loggedInNoRedirection(req, res) + }); }); }); }); @@ -115,7 +145,11 @@ export class AdminController { let email = req.params.email; UserRepository.getById(email).then((user: User) => { console.log(user); - res.render("admin/ancienneDemande", {title: "Demande", user: user, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/ancienneDemande", { + title: "Demande", + user: user, + userLogged: loggedInNoRedirection(req, res) + }); }) } @@ -136,7 +170,12 @@ export class AdminController { static offres(req: express.Request, res: express.Response) { FicheDePosteRepository.getDistinctRegion().then((regions: string[]) => { OfferRepository.getAll().then((offers: OffreDePoste[]) => { - res.render("admin/offres", {title: "Offres", offers: offers, regions: regions, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/offres", { + title: "Offres", + offers: offers, + regions: regions, + userLogged: loggedInNoRedirection(req, res) + }); }); }); } @@ -204,12 +243,29 @@ export class AdminController { }); OfferRepository.getById(Number.parseInt(idOffre)).then((offer: OffreDePoste) => { - res.render("admin/offre", {title: "Offre", offer: offer, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); + if (req.user.role == 'Administrateur') { + res.render("admin/offre", { + title: "Offre", + offer: offer, + alerts: alerts, + userLogged: loggedInNoRedirection(req, res) + }); + } else { + res.render("offre/offre", { + title: "Offre", + offer: offer, + userLogged: loggedInNoRedirection(req, res) + }); + } }) - }else{ + } else { let numero = req.params.numero; OfferRepository.getById(Number.parseInt(numero)).then((offer: OffreDePoste) => { - res.render("admin/modifierOffre", {title: "Modifier une offre", offer: offer, userLogged: loggedInNoRedirection(req, res)}); + res.render("admin/modifierOffre", { + title: "Modifier une offre", + offer: offer, + userLogged: loggedInNoRedirection(req, res) + }); }) } } @@ -225,7 +281,11 @@ export class AdminController { let alert = new Alert("danger", "L'offre n'a été supprimée"); alerts.push(alert); }); - res.redirect("/admin/offres"); + if (req.user.role == "Administrateur") { + res.redirect("/admin/offres"); + } else { + res.redirect("/recruteur/offres"); + } } } diff --git a/app/controllers/OfferController.ts b/app/controllers/OfferController.ts index f0a235f..86dbc33 100644 --- a/app/controllers/OfferController.ts +++ b/app/controllers/OfferController.ts @@ -86,8 +86,7 @@ export class OfferController { return res.render("offre/offre", { title: "Offre", offer: offer, - userLogged: loggedInNoRedirection(req, res), - csrfToken: req.session.csrfSecret + userLogged: loggedInNoRedirection(req, res) }); }).catch((err) => { console.log(err); diff --git a/app/controllers/RecruteurController.ts b/app/controllers/RecruteurController.ts index 5bd1e14..790f3ea 100644 --- a/app/controllers/RecruteurController.ts +++ b/app/controllers/RecruteurController.ts @@ -3,6 +3,7 @@ import {CandidatureRepository} from "../repository/CandidatureRepository"; import {Alert} from "../utils/Alert"; import {loggedInNoRedirection} from "../passport/passportFunctions"; import {OfferRepository} from "../repository/OfferRepository"; +import {User} from "../entity/User"; export class RecruteurController { static index(req: express.Request, res: express.Response) { @@ -12,22 +13,39 @@ export class RecruteurController { static candidatures(req: express.Request, res: express.Response) { //TODO get siren from user - let siren = '123456'; - let alerts: Alert[] = []; + let user: User = req.user as User; + let siren = user.organisation?.siren; + let alerts: Alert[] = []; + if (siren === undefined) { + siren = String(); + } CandidatureRepository.getBySiren(siren).then((candidatures) => { - res.render("recruteur/candidatures", {title: "Candidatures", candidatures: candidatures, userLogged: loggedInNoRedirection(req, res)}); + res.render("recruteur/candidatures", { + title: "Candidatures", + candidatures: candidatures, + userLogged: loggedInNoRedirection(req, res) + }); }).catch((err) => { alerts.push(new Alert("danger", "Erreur lors de la récupération des candidatures")); res.redirect("/recruteur"); }); + } static offres(req: express.Request, res: express.Response) { - let siren = '123456'; + let user: User = req.user as User; + let siren = user.organisation?.siren; let alerts: Alert[] = []; + if (siren === undefined) { + siren = String(); + } OfferRepository.getBySiren(siren).then((offers) => { - res.render("recruteur/offres", {title: "Offres", offers: offers, userLogged: loggedInNoRedirection(req, res)}); + res.render("recruteur/offres", { + title: "Offres", + offers: offers, + userLogged: loggedInNoRedirection(req, res) + }); }); } } diff --git a/app/routes/RecruterRouter.ts b/app/routes/RecruterRouter.ts index 97379e0..e131af2 100644 --- a/app/routes/RecruterRouter.ts +++ b/app/routes/RecruterRouter.ts @@ -1,7 +1,8 @@ import express from "express"; import {RecruteurController} from "../controllers/RecruteurController"; -import {offerRouter} from "./OfferRouter"; -const { passport, loggedIn, checkRole } = require("../passport/passportFunctions"); +import {AdminController} from "../controllers/AdminController"; + +const {passport, checkRole} = require("../passport/passportFunctions"); export const recruterRouter = express.Router(); recruterRouter.use(passport.initialize()); @@ -10,4 +11,7 @@ recruterRouter.use(passport.session()); recruterRouter.get("/", checkRole("Recruteur"), RecruteurController.index); recruterRouter.get("/candidatures", checkRole("Recruteur"), RecruteurController.candidatures); recruterRouter.get("/offres", RecruteurController.offres); +recruterRouter.get("/modifierOffre/:numero", AdminController.modifierOffre); +recruterRouter.post("/modifierOffre/:numero", AdminController.modifierOffre); +recruterRouter.get("/supprimerOffre/:numero", AdminController.supprimerOffre); diff --git a/app/table.sql b/app/table.sql index f4b3501..0768d88 100644 --- a/app/table.sql +++ b/app/table.sql @@ -20,13 +20,6 @@ CREATE TABLE `Organisation` `siege` varchar(128) NOT NULL, PRIMARY KEY (siren) ); --- --- Déchargement des données de la table `Organisation` --- - -INSERT INTO `Organisation` (`siren`, `nom`, `type`, `siege`) -VALUES ('123456', 'La banque', 'SARL', 'La défense'), - ('3345', 'Carrefour', 'SCI', 'Reuil Malmaison'); -- -------------------------------------------------------- @@ -158,6 +151,11 @@ CREATE TABLE `Piece` -- -------------------------------------------------------- #Insertion des données + +INSERT INTO `Organisation` (`siren`, `nom`, `type`, `siege`) +VALUES ('123456', 'La banque', 'SARL', 'La défense'), + ('3345', 'Carrefour', 'SCI', 'Reuil Malmaison'); + INSERT INTO FicheDePoste VALUES (0, 'En cours', 'Joe Doe', 'Développeur', 'Paris', 1, 35, 2000, 'Description', '123456'); INSERT INTO FicheDePoste @@ -167,3 +165,96 @@ INSERT INTO OffreDePoste VALUES (0, 'non publiée', '2020-12-31', 2, 'CV, LM', 1); INSERT INTO OffreDePoste VALUES (0, 'non publiée', '2020-12-31', 2, 'CV, LM', 2); + +-- Insertion des organisations +INSERT INTO Organisation (siren, nom, type, siege) +VALUES ('123456789', 'Acme Corporation', 'Technologie', 'Paris'), + ('987654321', 'Global Industries', 'Industrie', 'New York'), + ('567890123', 'Green Solutions', 'Environnement', 'Londres'); + +-- Insertion des fiches de poste pour Organisation A +INSERT INTO FicheDePoste (status, responsable, type_metier, lieu, teletravail, nb_heures, salaire, description, siren) +VALUES ('Ouverte', 'John Doe', 'Développeur Web', 'Paris', 1, 40, 50000, + 'Nous recherchons un développeur web expérimenté pour rejoindre notre équipe dynamique chez Acme Corporation. Le candidat idéal aura une solide expérience en développement front-end et back-end, ainsi qu\'une connaissance approfondie des langages de programmation tels que HTML, CSS, JavaScript et PHP. Vous serez responsable de la conception, du développement et de la maintenance de nos applications web, en travaillant en étroite collaboration avec les autres membres de l\'équipe.', + '123456789'), + ('Ouverte', 'Jane Smith', 'Ingénieur Logiciel', 'Paris', 0, 35, 60000, + 'Acme Corporation recherche un ingénieur logiciel passionné pour contribuer à la conception et au développement de nos produits logiciels. Vous serez responsable de la création de spécifications techniques, de la résolution de problèmes complexes et de l\'optimisation des performances des logiciels. Le candidat idéal aura une solide expérience en développement logiciel, une connaissance approfondie des langages de programmation tels que Java et C++, et une aptitude à travailler en équipe.', + '123456789'), + ('Fermée', 'Mark Johnson', 'Analyste financier', 'Paris', 1, 30, 45000, + 'Nous recherchons un analyste financier expérimenté pour rejoindre notre équipe chez Acme Corporation. Vos responsabilités comprendront l\'analyse des données financières, l\'évaluation des performances passées et la projection des résultats futurs. Le candidat idéal aura une solide compréhension des concepts financiers, une connaissance approfondie des outils d\'analyse financière et une capacité à fournir des recommandations stratégiques basées sur les résultats de l\'analyse.', + '123456789'), + ('Ouverte', 'Emily Wilson', 'Chef de projet', 'Paris', 1, 25, 55000, + 'Acme Corporation recherche un chef de projet talentueux pour superviser la planification, la mise en \œuvre et l\'exécution de nos projets. Vous serez responsable de la gestion de l\'équipe, de l\'affectation des ressources, du suivi des délais et de la communication avec les parties prenantes. Le candidat idéal aura une expérience avérée en gestion de projet, une solide compétence en leadership et une excellente capacité à résoudre les problèmes.', + '123456789'), + ('Ouverte', 'Daniel Brown', 'Spécialiste en marketing', 'Paris', 0, 20, 40000, + 'Acme Corporation cherche un spécialiste en marketing créatif pour développer et exécuter des stratégies de marketing innovantes. Vos responsabilités incluront la création de campagnes publicitaires, la gestion des médias sociaux, l\'analyse des données marketing et la collaboration avec les équipes internes pour atteindre les objectifs de vente et de notoriété de la marque. Le candidat idéal aura une connaissance approfondie du marketing numérique, des compétences en création de contenu et une capacité à travailler dans un environnement dynamique.', + '123456789'); + +-- Insertion des fiches de poste pour Organisation B +INSERT INTO FicheDePoste (status, responsable, type_metier, lieu, teletravail, nb_heures, salaire, description, siren) +VALUES ('Ouverte', 'Sarah Davis', 'Développeur Java', 'New York', 1, 40, 55000, + 'Global Industries est à la recherche d\'un développeur Java expérimenté pour rejoindre notre équipe talentueuse. Vous serez responsable du développement et de la maintenance de nos applications basées sur Java, ainsi que de la résolution des problèmes complexes et de l\'optimisation des performances. Le candidat idéal aura une solide expérience en développement Java, une connaissance approfondie des frameworks tels que Spring et Hibernate, et une passion pour la création de logiciels de qualité.', + '987654321'), + ('Ouverte', 'Michael Wilson', 'Analyste de données', 'New York', 0, 35, 60000, + 'Global Industries recherche un analyste de données compétent pour contribuer à l\'extraction, à l\'analyse et à l\'interprétation des données afin de fournir des informations exploitables à l\'entreprise. Vous serez responsable de la création de modèles analytiques, de la visualisation des données et de la génération de rapports pour soutenir la prise de décision stratégique. Le candidat idéal aura une solide expérience en analyse de données, une maîtrise des outils d\'analyse et une capacité à communiquer efficacement les résultats.', + '987654321'), + ('Ouverte', 'Jessica Taylor', 'Designer graphique', 'New York', 1, 30, 45000, + 'Nous recherchons un designer graphique créatif pour rejoindre notre équipe de design chez Global Industries. Vos responsabilités comprendront la création d\'éléments visuels attrayants, tels que des illustrations, des infographies et des maquettes, en utilisant des outils de conception graphique tels que Adobe Photoshop et Illustrator. Le candidat idéal aura une solide expérience en design graphique, une créativité exceptionnelle et une sensibilité esthétique.', + '987654321'), + ('Fermée', 'Andrew Clark', 'Gestionnaire de projet', 'New York', 1, 25, 50000, + 'Global Industries recherche un gestionnaire de projet expérimenté pour diriger et coordonner la réalisation de nos projets. Vous serez responsable de la planification, de l\'exécution et du suivi des projets, en veillant à ce qu\'ils respectent les délais, les budgets et les exigences de qualité. Le candidat idéal aura une solide expérience en gestion de projet, d\'excellentes compétences en leadership et une capacité à gérer efficacement les ressources.', + '987654321'), + ('Fermée', 'Olivia Green', 'Spécialiste en sécurité informatique', 'New York', 0, 20, 55000, + 'Global Industries est à la recherche d\'un spécialiste en sécurité informatique compétent pour protéger nos systèmes et données contre les menaces. Vous serez responsable de l\'évaluation des vulnérabilités, de la mise en place de mesures de sécurité, de la surveillance des activités suspectes et de la sensibilisation à la sécurité auprès du personnel. Le candidat idéal aura une solide expérience en sécurité informatique, une connaissance approfondie des normes et des outils de sécurité, et une capacité à rester à jour sur les dernières tendances en matière de sécurité.', + '987654321'); + +-- Insertion des fiches de poste pour Organisation C +INSERT INTO FicheDePoste (status, responsable, type_metier, lieu, teletravail, nb_heures, salaire, description, siren) +VALUES ('Fermée', 'Robert Johnson', 'Ingénieur en énergies renouvelables', 'Londres', 1, 30, 50000, + 'Green Solutions est à la recherche d\'un ingénieur en énergies renouvelables pour contribuer à la conception et à la mise en œuvre de solutions durables. Vous serez responsable de l\'évaluation des ressources énergétiques, de la planification des projets et de la supervision de l\'installation des équipements. Le candidat idéal aura une solide expertise en énergies renouvelables, une compréhension des technologies telles que l\'énergie solaire et éolienne, et un engagement envers la préservation de l\'environnement.', + '567890123'), + ('Ouverte', 'Sophia Roberts', 'Spécialiste en développement durable', 'Londres', 1, 25, 45000, + 'Green Solutions recherche un spécialiste en développement durable pour promouvoir des pratiques respectueuses de l\'environnement au sein de notre organisation. Vous serez responsable de l\'élaboration et de la mise en œuvre de stratégies de durabilité, de l\'évaluation des impacts environnementaux et de la sensibilisation aux enjeux environnementaux. Le candidat idéal aura une solide compréhension du développement durable, une connaissance des réglementations environnementales et une capacité à influencer positivement le comportement des employés et des partenaires.', + '567890123'), + ('Fermée', 'Alexander Brown', 'Analyste en gestion de l\'eau', 'Londres', 0, 20, 40000, + 'Green Solutions recherche un analyste en gestion de l\'eau pour évaluer l\'utilisation de l\'eau, identifier les opportunités d\'efficacité et proposer des solutions durables. Vos responsabilités comprendront l\'analyse des données sur l\'utilisation de l\'eau, la réalisation d\'études de faisabilité et la recommandation de pratiques d\'utilisation responsable de l\'eau. Le candidat idéal aura une expertise en gestion de l\'eau, une connaissance des technologies et des politiques liées à la gestion de l\'eau, et un intérêt pour la préservation des ressources en eau.', + '567890123'); + +-- Insertion des offres de poste pour les fiches de poste de l'Organisation A +INSERT INTO OffreDePoste (etat, date_validite, nb_piece, liste_piece, fiche) +VALUES ('Publiée', '2023-06-30', 2, 'Lettre de motivation, CV', 3), + ('Non publiée', '2023-06-25', 1, 'CV', 4), + ('Publiée', '2023-06-28', 3, 'Lettre de motivation, CV, Références', 5), + ('Non publiée', '2023-06-23', 2, 'Lettre de motivation, CV', 6), + ('Non publiée', '2023-06-26', 1, 'CV', 7); + +-- Insertion des offres de poste pour les fiches de poste de l'Organisation B +INSERT INTO OffreDePoste (etat, date_validite, nb_piece, liste_piece, fiche) +VALUES ('Non publiée', '2023-06-25', 2, 'Lettre de motivation, CV', 8), + ('Publiée', '2023-06-30', 1, 'CV', 9), + ('Non publiée', '2023-06-23', 2, 'Lettre de motivation, CV', 10), + ('Publiée', '2023-06-28', 3, 'Lettre de motivation, CV, Références', 11), + ('Non publiée', '2023-06-26', 1, 'CV', 12); + +-- Insertion des offres de poste pour les fiches de poste de l'Organisation C +INSERT INTO OffreDePoste (etat, date_validite, nb_piece, liste_piece, fiche) +VALUES ('Publiée', '2023-06-30', 2, 'Lettre de motivation, CV', 13), + ('Non publiée', '2023-06-25', 1, 'CV', 14), + ('Publiée', '2023-06-28', 3, 'Lettre de motivation, CV, Références', 15); + +INSERT INTO recrutement.Utilisateur (email, nom, prenom, telephone, date_creation, statut, password, role, + demande_organisation, siren) +VALUES ('admin@gmail.com', 'admin', 'admin', '060606060606', '2023-06-22', 1, + '$2b$10$.OeaoEtUOh290X2k.XE4pupqehMqM/bQe7EOLgrbgWxzXodVPKc0.', 'Administrateur', null, null); +INSERT INTO recrutement.Utilisateur (email, nom, prenom, telephone, date_creation, statut, password, role, + demande_organisation, siren) +VALUES ('recruteur@gmail.com', 'recruteur', 'recruteur', '0606060606', '2023-06-22', 1, + '$2b$10$bDBqTsUJTV53pXMcHdA1iOEfe/rbQHaQtHimjOjbDQiIndujsGuc2', 'Recruteur', 'acceptation', '567890123'); +INSERT INTO recrutement.Utilisateur (email, nom, prenom, telephone, date_creation, statut, password, role, + demande_organisation, siren) +VALUES ('candidat@gmail.com', 'candidat', 'candidat', '0606060606', '2023-06-22', 1, + '$2b$10$bDBqTsUJTV53pXMcHdA1iOEfe/rbQHaQtHimjOjbDQiIndujsGuc2', 'Candidat', null, null); +INSERT INTO recrutement.Utilisateur (email, nom, prenom, telephone, date_creation, statut, password, role, + demande_organisation, siren) +VALUES ('candidat2@gmail.com', 'candidat2', 'candidat2', '0606060606', '2023-06-22', 1, + '$2b$10$bDBqTsUJTV53pXMcHdA1iOEfe/rbQHaQtHimjOjbDQiIndujsGuc2', 'Candidat', null, null); diff --git a/app/views/admin/modifierOffre.ejs b/app/views/admin/modifierOffre.ejs index 1cd5f7e..ae73096 100644 --- a/app/views/admin/modifierOffre.ejs +++ b/app/views/admin/modifierOffre.ejs @@ -1,9 +1,20 @@ -<%- include('../partials/adminHeader.ejs') %> +<% if (user) { %> + <% if (user.role === 'Administrateur') { %> + <%- include('partials/adminHeader.ejs') %> + <% } else { %> + <%- include('../partials/recruteurHeader.ejs') %> + <% } %> +<% } %>
- Image création d'entreprise + + Image création d'entreprise + + +

Offre : <%= offer.ficheDePoste.typeMetier %>

diff --git a/app/views/admin/offre.ejs b/app/views/admin/offre.ejs index c38529c..6574974 100644 --- a/app/views/admin/offre.ejs +++ b/app/views/admin/offre.ejs @@ -111,19 +111,20 @@
-