From ff86480fc577bb0f5a3d33bd8891e3ae934b2b7e Mon Sep 17 00:00:00 2001 From: Baptiste Buvron Date: Tue, 20 Jun 2023 19:50:05 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20-=20affichage=20d'une=20candidature=20po?= =?UTF-8?q?ur=20un=20recruteur=20et=20un=20candidat=20-=20r=C3=A9cup=C3=A9?= =?UTF-8?q?ration=20de=20l'user=20pour=20l'affichage=20des=20utilisateurs?= =?UTF-8?q?=20-=20Possibili=C3=A9=20de=20t=C3=A9l=C3=A9charger=20un=20fich?= =?UTF-8?q?ier=20-=20Ajout=20d'un=20middleware=20pour=20acc=C3=A9der=20?= =?UTF-8?q?=C3=A0=20l'utilisateur=20courant=20dans=20les=20vues=20-=20Affi?= =?UTF-8?q?chage=20du=20nom=20de=20l'organisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/ApiController.ts | 2 - app/controllers/CandidatureController.ts | 50 ++++++++++++-- app/controllers/FicheController.ts | 3 - app/controllers/OfferController.ts | 20 +++--- app/entity/Candidature.ts | 5 +- app/entity/Piece.ts | 3 +- app/index.ts | 3 +- app/public/js/filter.js | 21 +++--- app/repository/CandidatureRepository.ts | 88 ++++++++++++++++++++++-- app/repository/FichierRepository.ts | 21 ------ app/repository/OfferRepository.ts | 4 +- app/repository/PieceRepository.ts | 57 +++++++++++++++ app/routes/MainRouter.ts | 38 +++++----- app/views/candidature.ejs | 71 +++++++++++++++++++ app/views/candidatures.ejs | 19 ++--- app/views/index.ejs | 2 +- app/views/recruteur/candidatures.ejs | 7 +- app/views/recruteur/offres.ejs | 2 +- 18 files changed, 326 insertions(+), 90 deletions(-) delete mode 100644 app/repository/FichierRepository.ts create mode 100644 app/repository/PieceRepository.ts create mode 100644 app/views/candidature.ejs diff --git a/app/controllers/ApiController.ts b/app/controllers/ApiController.ts index 96ff66b..8e99a56 100644 --- a/app/controllers/ApiController.ts +++ b/app/controllers/ApiController.ts @@ -2,8 +2,6 @@ import {OfferRepository} from "../repository/OfferRepository"; import {OffreDePoste} from "../entity/OffreDePoste"; import express from "express"; import {FilterOffer} from "../utils/FilterOffer"; -import {UserRepository} from "../repository/UserRepository"; -import {User} from "../entity/User"; export class ApiController { static getOffers(req: express.Request, res: express.Response) { diff --git a/app/controllers/CandidatureController.ts b/app/controllers/CandidatureController.ts index 3606d0d..ef62253 100644 --- a/app/controllers/CandidatureController.ts +++ b/app/controllers/CandidatureController.ts @@ -7,7 +7,7 @@ import {CandidatureRepository} from "../repository/CandidatureRepository"; import {Candidature} from "../entity/Candidature"; import {StatutCandidatureEnum} from "../utils/StatutCandidatureEnum"; import {Piece} from "../entity/Piece"; -import {PieceRepository} from "../repository/FichierRepository"; +import {PieceRepository} from "../repository/PieceRepository"; import {loggedInNoRedirection} from "../passport/passportFunctions"; export class CandidatureController { @@ -64,7 +64,12 @@ export class CandidatureController { } } - res.render("candidater", {title: "Candidater", offer: offer, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); + res.render("candidater", { + title: "Candidater", + offer: offer, + alerts: alerts, + userLogged: loggedInNoRedirection(req, res) + }); } ) @@ -73,12 +78,49 @@ export class CandidatureController { }); } + static async getFile(req: express.Request, res: express.Response) { + let id = req.params.id; + //TODO vérifier que l'utilisateur est bien un candidat ou un recruteur et qu'il a le droit d'accéder au fichier + try { + const piece = await PieceRepository.getById(Number(id)); + if (!piece) { + throw new Error("File not found"); + } + res.download(piece.url); + } catch (err) { + res.statusCode = 404; + res.send("File not found"); + } + } + + static candidature(req: express.Request, res: express.Response) { + let email = req.params.email; + let offerNumber = req.params.numero; + + CandidatureRepository.getById(email, offerNumber).then((candidature) => { + if (candidature) { + return res.render("candidature", { + title: "Candidature", + candidature: candidature, + userLogged: loggedInNoRedirection(req, res) + }); + } + return res.redirect("/"); + }).catch((err) => { + return res.redirect("/"); + }); + + } static candidatures(req: express.Request, res: express.Response) { //TODO Vérifier que l'utilisateur est bien un candidat - let user: User = new User('candidat1@example.com', 'Doe', 'John', '123456789', new Date(), true, 'password123', 'Candidat', 'En attente', null); + let user: User = req.user as User; CandidatureRepository.getByUser(user).then((candidatures) => { - res.render("candidatures", {title: "Mes candidatures", candidatures: candidatures, userLogged: loggedInNoRedirection(req, res)}); + res.render("candidatures", { + title: "Mes candidatures", + candidatures: candidatures, + userLogged: loggedInNoRedirection(req, res) + }); }).catch((err) => { console.log(err); diff --git a/app/controllers/FicheController.ts b/app/controllers/FicheController.ts index abb7cd3..8f96863 100644 --- a/app/controllers/FicheController.ts +++ b/app/controllers/FicheController.ts @@ -11,8 +11,6 @@ export class FicheController { if (req.method === "POST") { //TODO validation data let teletravail: boolean = req.body.teletravail === "on"; - //TODO get the siren from the recruiter - //random number 9 digits let siren: string = req.user.organisation?.siren as string; let nbHeures: number = parseInt(req.body.nbHeures); @@ -41,7 +39,6 @@ export class FicheController { }); } - //TODO get the siren from the recruiter res.render("fiche/creation", {title: "Créer une fiche de poste", alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); } diff --git a/app/controllers/OfferController.ts b/app/controllers/OfferController.ts index c7370ed..53d4612 100644 --- a/app/controllers/OfferController.ts +++ b/app/controllers/OfferController.ts @@ -13,14 +13,12 @@ export class OfferController { public static async creation(req: express.Request, res: express.Response) { const alerts: Alert[] = []; - console.log(req.method); if (req.method === "POST") { let csrfToken = req.body._csrf; if (!csrfValidation(req, csrfToken)) { alerts.push(new Alert("danger", "Erreur CSRF")); - //TODO message d'erreur return res.redirect("/logout"); } //TODO validation data @@ -48,7 +46,6 @@ export class OfferController { nbPiece, listePiece, ficheDePoste); - //TODO save the ficheDePoste in the database await OfferRepository.create(offreDePoste).then((offreDePoste) => { let alert = new Alert("success", "L'offre a été créée."); alerts.push(alert); @@ -67,20 +64,19 @@ export class OfferController { } //TODO selectionner seulement les fiches de postes de l'organisation du recruteur - let ficheDePostes: FicheDePoste[] = await FicheDePosteRepository.getAll(); + let siren: string = req.user.organisation?.siren as string; + let ficheDePostes: FicheDePoste[] = await FicheDePosteRepository.getBySiren(siren); if (ficheDePostes.length === 0) { let alert = new Alert("danger", "Vous n'avez pas encore créé de fiche de poste."); alerts.push(alert); return res.redirect("/fiche-de-poste/creation"); } - FicheDePosteRepository.getAll().then((ficheDePostes) => { - return res.render("offre/creation", { - title: "Créer une offre", - ficheDePostes: ficheDePostes, - alerts: alerts, - userLogged: loggedInNoRedirection(req, res), - csrfToken: req.session.csrfSecret - }); + return res.render("offre/creation", { + title: "Créer une offre", + ficheDePostes: ficheDePostes, + alerts: alerts, + userLogged: loggedInNoRedirection(req, res), + csrfToken: req.session.csrfSecret }); } } diff --git a/app/entity/Candidature.ts b/app/entity/Candidature.ts index a0ef598..3ca97c5 100644 --- a/app/entity/Candidature.ts +++ b/app/entity/Candidature.ts @@ -1,6 +1,7 @@ import {User} from "./User"; import {OffreDePoste} from "./OffreDePoste"; import {StatutCandidatureEnum} from "../utils/StatutCandidatureEnum"; +import {Piece} from "./Piece"; /** * Candidature @@ -15,13 +16,15 @@ export class Candidature { offre: OffreDePoste; statut: StatutCandidatureEnum; motivation: string; + pieces: Piece[] | undefined; - constructor(date: Date, candidat: User, offre: OffreDePoste, status: StatutCandidatureEnum, motivation: string) { + constructor(date: Date, candidat: User, offre: OffreDePoste, status: StatutCandidatureEnum, motivation: string, pieces?: Piece[]) { this.date = date; this.candidat = candidat; this.offre = offre; this.statut = status; this.motivation = motivation; + this.pieces = pieces; } } \ No newline at end of file diff --git a/app/entity/Piece.ts b/app/entity/Piece.ts index 32fccda..d3d4acd 100644 --- a/app/entity/Piece.ts +++ b/app/entity/Piece.ts @@ -8,10 +8,11 @@ export class Piece { candidat: User; offre: OffreDePoste; - constructor(nom: string, url: string, candidat: User, offre: OffreDePoste) { + constructor(nom: string, url: string, candidat: User, offre: OffreDePoste, id ?: number) { this.nom = nom; this.url = url; this.candidat = candidat; this.offre = offre; + this.id = id; } } \ No newline at end of file diff --git a/app/index.ts b/app/index.ts index d2cad0a..f2468fd 100644 --- a/app/index.ts +++ b/app/index.ts @@ -8,6 +8,7 @@ import {ficheRouter} from "./routes/FicheRouter"; import bodyParser from "body-parser"; import {recruterRouter} from "./routes/RecruterRouter"; import {apiRouter} from "./routes/ApiRouter"; + const {passport} = require("./passport/passportFunctions"); dotenv.config(); @@ -33,6 +34,6 @@ app.use("/api", apiRouter); const port = process.env.PORT || 8000; app.listen(port, () => { - console.log(`Example app listening on port ${port}`) + console.log(`web-app-recrutement listening on port ${port}`) }); diff --git a/app/public/js/filter.js b/app/public/js/filter.js index 10cf6c9..1a01be2 100644 --- a/app/public/js/filter.js +++ b/app/public/js/filter.js @@ -21,16 +21,17 @@ function filterOffer() { } let filter = "salary=" + salary + region; //Get all the offers from the /api/offers route and adding the filter parameters - fetch("/api/offers?" + filter).then(r => r.json()).then(offers => { - let offersDiv = document.getElementById("offers"); - if (offers.length === 0) { - offersDiv.innerHTML = "Aucune offre ne correspond à vos critères"; - return; + fetch("/api/offers?" + filter).then(r => r.json()) + .then(offers => { + let offersDiv = document.getElementById("offers"); + if (offers.length === 0) { + offersDiv.innerHTML = "Aucune offre ne correspond à vos critères"; + return; + } + offersDiv.innerHTML = ""; + offersDiv.append(...generateOffers(offers)); } - offersDiv.innerHTML = ""; - offersDiv.append(...generateOffers(offers)); - } - ); + ); } @@ -46,7 +47,7 @@ function generateOfferPrototype(offer) { p1.innerHTML = offer.ficheDePoste.description; const p2 = document.createElement('p'); - p2.innerHTML = `Organisation: ${offer.ficheDePoste.siren}`; + p2.innerHTML = `Organisation: ${offer.ficheDePoste.organisation.nom}`; const a = document.createElement('a'); a.href = `/canditature/${offer.numero}`; diff --git a/app/repository/CandidatureRepository.ts b/app/repository/CandidatureRepository.ts index 88eb2b4..898cccf 100644 --- a/app/repository/CandidatureRepository.ts +++ b/app/repository/CandidatureRepository.ts @@ -4,6 +4,7 @@ import {User} from "../entity/User"; import {OffreDePoste} from "../entity/OffreDePoste"; import {FicheDePoste} from "../entity/FicheDePoste"; import {Organisation} from "../entity/Organisation"; +import {PieceRepository} from "./PieceRepository"; export class CandidatureRepository { static create(candidature: Candidature): Promise { @@ -39,9 +40,9 @@ export class CandidatureRepository { FDP.salaire, FDP.description, FDP.siren, - O.nom as nom_organisation, - O.type as type_organisation, - O.siege as siege_organisation + O.nom as nom_organisation, + O.type as type_organisation, + O.siege as siege_organisation FROM Candidature LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero @@ -100,11 +101,15 @@ export class CandidatureRepository { FDP.nb_heures, FDP.salaire, FDP.description, - FDP.siren + FDP.siren, + O.nom, + O.type, + O.siege FROM Candidature LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero LEFT JOIN Utilisateur U on Candidature.candidat = U.email + LEFT JOIN Organisation O on FDP.siren = O.siren WHERE FDP.siren = ?`; return new Promise((resolve, reject) => { pool.query(query, [siren], (err, result) => { @@ -113,7 +118,8 @@ export class CandidatureRepository { } let candidatures: Candidature[] = []; for (let i = 0; i < result.length; i++) { - let fiche = new FicheDePoste(result[i].fiche_numero, result[i].fiche_statut, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nb_heures, result[i].salaire, result[i].description, result[i].siren); + let organisation = new Organisation(result[i].siren, result[i].nom, result[i].type, result[i].siege); + let fiche = new FicheDePoste(result[i].fiche_numero, result[i].fiche_statut, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nb_heures, result[i].salaire, result[i].description, result[i].siren, organisation); let offre = new OffreDePoste(result[i].offre_numero, result[i].etat, result[i].date_validite, result[i].nb_piece, result[i].liste_piece, fiche); let candidat = new User(result[i].candidat, result[i].email, result[i].prenom, result[i].telephone, result[i].date_creation, result[i].user_statut, result[i].password, result[i].role, result[i].demande_organisation, result[i].user_siren); candidatures.push(new Candidature( @@ -129,4 +135,76 @@ export class CandidatureRepository { }); } + static getById(email: string, offerNumber: string): Promise { + const query = `SELECT Candidature.candidat, + U.email, + U.nom as user_nom, + U.prenom, + U.telephone, + U.date_creation, + U.statut as user_statut, + U.password, + U.role, + U.demande_organisation, + U.siren as user_siren, + Candidature.offre, + Candidature.statut as candidature_statut, + Candidature.motivation, + Candidature.date_candidature, + ODP.numero as offre_numero, + ODP.etat, + ODP.date_validite, + ODP.nb_piece, + ODP.liste_piece, + FDP.numero as fiche_numero, + FDP.status as fiche_statut, + FDP.responsable, + FDP.type_metier, + FDP.lieu, + FDP.teletravail, + FDP.nb_heures, + FDP.salaire, + FDP.description, + FDP.siren, + O.nom, + O.type, + O.siege + FROM Candidature + LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero + LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero + LEFT JOIN Utilisateur U on Candidature.candidat = U.email + LEFT JOIN Organisation O on FDP.siren = O.siren + WHERE Candidature.candidat = ? + AND Candidature.offre = ?`; + + return new Promise((resolve, reject) => { + pool.query(query, [email, offerNumber], async (err, result) => { + if (err) { + return reject(err); + } + if (result.length === 0) { + return resolve(null); + } + let pieces = await PieceRepository.getByCandidature(result[0].email, result[0].offre_numero).then((pieces) => { + return pieces; + }).catch((err) => { + return []; + }); + + let organisation = new Organisation(result[0].siren, result[0].nom, result[0].type, result[0].siege); + let fiche = new FicheDePoste(result[0].fiche_numero, result[0].fiche_statut, result[0].responsable, result[0].type_metier, result[0].lieu, result[0].teletravail, result[0].nb_heures, result[0].salaire, result[0].description, result[0].siren, organisation); + let offre = new OffreDePoste(result[0].offre_numero, result[0].etat, result[0].date_validite, result[0].nb_piece, result[0].liste_piece, fiche); + let candidat = new User(result[0].candidat, result[0].user_nom, result[0].prenom, result[0].telephone, result[0].date_creation, result[0].user_statut, result[0].password, result[0].role, result[0].demande_organisation, result[0].user_siren); + return resolve(new Candidature( + result[0].date_candidature, + candidat, + offre, + result[0].candidature_statut, + result[0].motivation, + pieces + )); + }); + }); + + } } diff --git a/app/repository/FichierRepository.ts b/app/repository/FichierRepository.ts deleted file mode 100644 index 00b183e..0000000 --- a/app/repository/FichierRepository.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {Piece} from "../entity/Piece"; -import {pool} from "../database"; - -export class PieceRepository { - static create(fichier: Piece): Promise { - const query = `INSERT INTO Piece (nom, url, candidat, offre) - VALUES (?, ?, ?, ?)`; - return new Promise((resolve, reject) => { - pool.query(query, [fichier.nom, fichier.url, fichier.candidat.email, fichier.offre.numero], (err, result) => { - if (err) { - return reject(err); - } - fichier.id = result.insertId; - return resolve(fichier); - }); - } - ); - } - - -} \ No newline at end of file diff --git a/app/repository/OfferRepository.ts b/app/repository/OfferRepository.ts index 54d9689..eb40c4b 100644 --- a/app/repository/OfferRepository.ts +++ b/app/repository/OfferRepository.ts @@ -100,6 +100,7 @@ export class OfferRepository { const query = `SELECT * FROM ${OfferRepository.tableName} LEFT JOIN FicheDePoste ON FicheDePoste.numero = OffreDePoste.fiche + LEFT JOIN Organisation O on FicheDePoste.siren = O.siren WHERE FicheDePoste.siren = ?`; return new Promise( (resolve, reject) => { @@ -109,7 +110,8 @@ export class OfferRepository { } let offers: OffreDePoste[] = []; for (let i = 0; i < result.length; i++) { - let ficheDePoste = new FicheDePoste(result[i].fiche, result[i].status, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nbheure, result[i].salaire, result[i].description, result[i].siren); + let organisation = new Organisation(result[i].siren, result[i].nom, result[i].type, result[i].siege); + let ficheDePoste = new FicheDePoste(result[i].fiche, result[i].status, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nbheure, result[i].salaire, result[i].description, result[i].siren, organisation); let offer = new OffreDePoste(result[i].numero, result[i].etat, result[i].date_validite, result[i].nb_piece, result[i].liste_piece, ficheDePoste); offers.push(offer); } diff --git a/app/repository/PieceRepository.ts b/app/repository/PieceRepository.ts new file mode 100644 index 0000000..69376bb --- /dev/null +++ b/app/repository/PieceRepository.ts @@ -0,0 +1,57 @@ +import {Piece} from "../entity/Piece"; +import {pool} from "../database"; + +export class PieceRepository { + static create(fichier: Piece): Promise { + const query = `INSERT INTO Piece (nom, url, candidat, offre) + VALUES (?, ?, ?, ?)`; + return new Promise((resolve, reject) => { + pool.query(query, [fichier.nom, fichier.url, fichier.candidat.email, fichier.offre.numero], (err, result) => { + if (err) { + return reject(err); + } + fichier.id = result.insertId; + return resolve(fichier); + }); + } + ); + } + + static getByCandidature(email: string, number: number): Promise { + const query = `SELECT * + FROM Piece + WHERE candidat = ? + AND offre = ?`; + return new Promise((resolve, reject) => { + pool.query(query, [email, number], (err, result) => { + if (err) { + return reject(err); + } + let pieces: Piece[] = []; + for (let row of result) { + let piece: Piece = new Piece(row.nom, row.url, row.candidat, row.offre, row.id); + pieces.push(piece); + } + return resolve(pieces); + }); + }); + } + + static getById(id: number): Promise { + const query = `SELECT * + FROM Piece + WHERE id = ?`; + return new Promise((resolve, reject) => { + pool.query(query, [id], (err, result) => { + if (err) { + return reject(err); + } + let row = result[0]; + let piece: Piece = new Piece(row.nom, row.url, row.candidat, row.offre, row.id); + return resolve(piece); + }); + }); + } + + +} \ No newline at end of file diff --git a/app/routes/MainRouter.ts b/app/routes/MainRouter.ts index e228efc..796adee 100644 --- a/app/routes/MainRouter.ts +++ b/app/routes/MainRouter.ts @@ -4,16 +4,16 @@ import multer, {Multer} from "multer"; import {CandidatureController} from "../controllers/CandidatureController"; import {createCSRFToken} from "../middlewares/CSRFMiddlewares"; -const { v4: uuidv4 } = require("uuid"); +const {v4: uuidv4} = require("uuid"); const session = require("express-session"); const FileStore = require("session-file-store")(session); -const { passport, checkRole} = require("../passport/passportFunctions"); +const {passport, checkRole} = require("../passport/passportFunctions"); export const defaultRouter = Router(); defaultRouter.use( session({ - genid: (req:any) => { + genid: (req: any) => { return uuidv4(); }, store: new FileStore(), @@ -43,6 +43,10 @@ const upload: Multer = multer({ defaultRouter.use(passport.initialize()); defaultRouter.use(passport.session()); defaultRouter.use(createCSRFToken) +defaultRouter.use(function (req, res, next) { + res.locals.user = req.user; + next(); +}); defaultRouter.get("/", HomeController.index); defaultRouter.get("/login", HomeController.login); @@ -56,14 +60,14 @@ defaultRouter.post("/canditature/:numero", checkRole("Candidat"), upload.fields( {name: 'cv', maxCount: 1}, {name: 'lettre', maxCount: 1} ]), CandidatureController.candidater); - - +defaultRouter.get("/candidature/:email/:numero", CandidatureController.candidature); +defaultRouter.get("/download/:id", CandidatureController.getFile); defaultRouter.post( "/login", function (req, res, next) { - passport.authenticate("login", async (err:any, user:any, info:any) => { + passport.authenticate("login", async (err: any, user: any, info: any) => { if (err) { return next(err); } @@ -75,11 +79,11 @@ defaultRouter.post( let role = user.role; let url; if (role == "Administrateur") { - url="admin"; - } else if(role == "Recruteur"){ - url="recruteur"; - }else{ - url=""; + url = "admin"; + } else if (role == "Recruteur") { + url = "recruteur"; + } else { + url = ""; } return res.redirect(`/${url}`); @@ -88,16 +92,16 @@ defaultRouter.post( } ); -defaultRouter.post("/register", async(req, res, next)=>{ - passport.authenticate("register", async function(error:any, user:any, info:any){ - if(error){ +defaultRouter.post("/register", async (req, res, next) => { + passport.authenticate("register", async function (error: any, user: any, info: any) { + if (error) { return next(error.message); } - if(!user){ + if (!user) { res.redirect(`/register?message=${info.message}`); } - req.login(user, async (error:any) => { + req.login(user, async (error: any) => { if (error) { return next(error); } @@ -107,7 +111,7 @@ defaultRouter.post("/register", async(req, res, next)=>{ }); defaultRouter.get("/logout", async (req, res) => { - req.logout(function (err:any) { + req.logout(function (err: any) { if (err) { return err; } diff --git a/app/views/candidature.ejs b/app/views/candidature.ejs new file mode 100644 index 0000000..6132f06 --- /dev/null +++ b/app/views/candidature.ejs @@ -0,0 +1,71 @@ +<% if (user) { %> + <% if (user.role === 'Recruteur') { %> + <%- include('partials/recruteurheader.ejs') %> + <% } else { %> + <%- include('partials/header.ejs') %> + <% } %> +<% } %> + + +
+
+
+ +
+ +
Date de la candidature : <%= candidature.date.getDate() %>/<%= candidature.date.getMonth() %> + /<%= candidature.date.getFullYear() %>
+
+
+ + +
+
+ + +
+
+ +
+ +
+ +
+ + +
+
+ + + +
+
+ + + + +
+
Informations soumises :
+
+ + +
+
+ <% candidature.pieces.forEach((piece) => { + %> + Télécharger le document + : <%= piece.nom %> + <% }) %> +
+ +
+
+
+ + \ No newline at end of file diff --git a/app/views/candidatures.ejs b/app/views/candidatures.ejs index f7c0f01..3cdfdca 100644 --- a/app/views/candidatures.ejs +++ b/app/views/candidatures.ejs @@ -4,14 +4,17 @@

Mes candidatures

<% candidatures.forEach((candidature) => { %> -
-

<%= candidature.offre.ficheDePoste.typeMetier %> <%= candidature.offre.ficheDePoste.salaire %> € -

-

<%= candidature.offre.ficheDePoste.description %>

-

Organisation : Nom de l'<%= candidature.offre.ficheDePoste.siren %>

-

Status : <%= candidature.statut %> €

-
+
+

<%= candidature.offre.ficheDePoste.typeMetier %> <%= candidature.offre.ficheDePoste.salaire %> € +

+

<%= candidature.offre.ficheDePoste.description %>

+

Organisation : Nom de l'<%= candidature.offre.ficheDePoste.siren %>

+

Status : <%= candidature.statut %> €

+ Voir la + candidature +
<% }) %>
diff --git a/app/views/index.ejs b/app/views/index.ejs index f44e547..a70d710 100644 --- a/app/views/index.ejs +++ b/app/views/index.ejs @@ -42,7 +42,7 @@ class="badge text-bg-secondary float-end"><%= offer.ficheDePoste.salaire %> €

<%= offer.ficheDePoste.description %>

-

Organisation : <%= offer.ficheDePoste.siren %>

+

Organisation : <%= offer.ficheDePoste.organisation.nom %>

Postuler <% }) %> diff --git a/app/views/recruteur/candidatures.ejs b/app/views/recruteur/candidatures.ejs index 1f66f11..2bcc4c8 100644 --- a/app/views/recruteur/candidatures.ejs +++ b/app/views/recruteur/candidatures.ejs @@ -9,8 +9,11 @@ class="badge text-bg-secondary float-end"><%= candidature.offre.ficheDePoste.salaire %> €

<%= candidature.offre.ficheDePoste.description %>

-

Organisation : Nom de l'<%= candidature.offre.ficheDePoste.siren %>

-

Status : <%= candidature.statut %> €

+

Organisation : <%= candidature.offre.ficheDePoste.organisation.nom %>

+

Status : <%= candidature.statut %> €

+ Etudier la + candidature <% }) %> diff --git a/app/views/recruteur/offres.ejs b/app/views/recruteur/offres.ejs index 0db7a51..2d828c7 100644 --- a/app/views/recruteur/offres.ejs +++ b/app/views/recruteur/offres.ejs @@ -9,7 +9,7 @@ class="badge text-bg-secondary float-end">45000 €

<%= offer.ficheDePoste.description %>

-

Organisation : <%= offer.ficheDePoste.siren %>

+

Organisation : <%= offer.ficheDePoste.organisation.nom %>

<% }) %>