From a5bef7097e9a5ea76f1fe9a986e37e124bdd4ac9 Mon Sep 17 00:00:00 2001 From: firdaous elhalafi Date: Sat, 7 Oct 2023 16:03:34 +0200 Subject: [PATCH] ajout des champs questions reponses pour les annonces --- routes/announcement.js | 78 ++++++++++++++++++++++++++++++++-- routes/index.js | 10 ++++- schemas/models.js | 10 ++++- views/announcement_details.pug | 41 ++++++++++++++++++ views/announcements.pug | 32 ++++++++++---- 5 files changed, 157 insertions(+), 14 deletions(-) diff --git a/routes/announcement.js b/routes/announcement.js index 383528e..2c7e548 100644 --- a/routes/announcement.js +++ b/routes/announcement.js @@ -9,7 +9,7 @@ const Announcement = models.Announcement; const isAuthenticated = routes.isAuthenticated; const isAgent = routes.isAgent; const isAgentAddAnnouncements = routes.isAgentAddAnnouncements; - +const isConsultant = routes.isConsultant; // Route pour récupérer toutes les annonces router.get('/', async (req, res) => { try { @@ -44,6 +44,64 @@ router.get('/:id', async (req, res) => { } }); +router.post('/:id/ask', isAuthenticated, isConsultant, async (req, res) => { + const announcementId = req.params.id; + const { question } = req.body; + const user = req.user; + + try { + const announcement = await Announcement.findById(announcementId); + + if (!announcement) { + return res.status(404).json({ message: 'Annonce non trouvée' }); + } + + announcement.questions.push({ + user: user.username, + question + }); + + await announcement.save(); + + res.redirect(`/announcements/${announcementId}`); + } catch (error) { + res.status(500).json({ message: error.message }); + } +}); + +router.post('/:id/question/:questionId/answer', isAuthenticated, isAgent, async (req, res) => { + const announcementId = req.params.id; + const questionId = req.params.questionId; + const { answer } = req.body; + const user = req.user; + + try { + const announcement = await Announcement.findById(announcementId); + + if (!announcement) { + return res.status(404).json({ message: 'Annonce non trouvée' }); + } + + if (user.username !== announcement.userName) { + return res.status(404).json({ message: 'User non autorisée' }); + } + + const question = announcement.questions.id(questionId); + + if (!question) { + return res.status(404).json({ message: 'Question non trouvée' }); + } + + question.answers.push({ user: user.username, answer }); + await announcement.save(); + + res.redirect(`/announcements/${announcementId}`); + } catch (error) { + res.status(500).json({ message: error.message }); + } +}); + + router.post('/add-announcement', isAuthenticated, isAgent, upload.array('photos', ), async (req, res) => { const { title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate} = req.body; const photos = req.files.map(file => file.filename); @@ -74,13 +132,19 @@ router.post('/add-announcement', isAuthenticated, isAgent, upload.array('photos' // route to display form to update an ad router.get('/update/:id', isAuthenticated, isAgent, async (req, res) => { try { + const user = req.user; const announcementId = req.params.id; + const announcementDetails = await Announcement.findById(announcementId); if (!announcementDetails) { return res.status(404).json({ message: 'Announcement not found' }); } + if (user.username !== announcementDetails.userName) { + return res.status(404).json({ message: 'User non autorisée' }); + } + res.render('update_announcement', { announcement: announcementDetails, user: req.user }); } catch (error) { res.status(500).json({ message: error.message }); @@ -90,8 +154,9 @@ router.get('/update/:id', isAuthenticated, isAgent, async (req, res) => { // Route to handle update of an ad router.post('/update/:id', isAuthenticated, isAgent, upload.array('photos', ), async (req, res) => { const announcementId = req.params.id; + const user = req.user; const { title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate } = req.body; - photos = []; + let photos = []; if (req.files && req.files.length > 0) { photos = req.files.map(file => file.filename); } @@ -116,6 +181,9 @@ router.post('/update/:id', isAuthenticated, isAgent, upload.array('photos', ), a return res.status(404).json({ message: 'annonce non trouvée' }); } + if (user.username !== updatedAnnouncement.userName) { + return res.status(404).json({ message: 'User non autorisée' }); + } res.redirect('/announcements'); } catch (error) { res.status(500).json({ message: error.message }); @@ -125,11 +193,15 @@ router.post('/update/:id', isAuthenticated, isAgent, upload.array('photos', ), a router.get('/delete/:id', isAuthenticated, isAgent, async (req, res) => { try { const announcementId = req.params.id; + const user = req.user; + const deletedAnnouncement = await Announcement.findByIdAndRemove(announcementId); if (!deletedAnnouncement) { return res.status(404).json({ message: 'annonce non trouvée' }); } - + if (user.username !== deletedAnnouncement.userName) { + return res.status(404).json({ message: 'User non autorisée' }); + } res.redirect('/announcements'); } catch (error) { res.status(500).json({ message: error.message }); diff --git a/routes/index.js b/routes/index.js index ab27826..2d3ef7f 100644 --- a/routes/index.js +++ b/routes/index.js @@ -108,10 +108,18 @@ const isAgent = (req, res, next) => { return res.status(403).json({ message: 'Vous n\'êtes pas autorisé à effectuer cette action.' }); }; +const isConsultant = (req, res, next) => { + if (req.user && !req.user.isAgent) { + return next(); + } + return res.status(403).json({ message: 'Vous n\'êtes pas autorisé à effectuer cette action.' }); +}; + module.exports = { router: router, isAuthenticated: isAuthenticated, setUserIfAuthenticated: setUserIfAuthenticated, isAgent: isAgent, - isAgentAddAnnouncements: isAgentAddAnnouncements + isAgentAddAnnouncements: isAgentAddAnnouncements, + isConsultant: isConsultant }; \ No newline at end of file diff --git a/schemas/models.js b/schemas/models.js index ba61067..26bdbc3 100644 --- a/schemas/models.js +++ b/schemas/models.js @@ -31,7 +31,15 @@ const announcementSchema = new Schema({ price: { type:Number, required: true }, availabilityDate: { type: Date, required: true }, photos:{ type: [String] }, - userName: { type: String, required: true } + userName: { type: String, required: true }, + questions: [ + { + user: { type: String, required: true }, + question: { type: String, required: true }, + answers: [ { answer : { type: String } } ], + date: { type: Date, default: Date.now } + } + ] }); const User = mongoose.model('User', userSchema); diff --git a/views/announcement_details.pug b/views/announcement_details.pug index 2e213ac..7a7c87f 100644 --- a/views/announcement_details.pug +++ b/views/announcement_details.pug @@ -28,3 +28,44 @@ block content a.btn.btn-danger(href=`/announcements/delete/${announcement._id}`) Supprimer l'annonce a.btn.btn-secondary(href="/announcements") Annuler + .mt-3 + + if user && !user.isAgent + h2.card-title.mb-4 Mes Questions et Réponses + each question in announcement.questions + if question.user === user.username + .card.mb-3 + .card-body + h5.card-title Question + p.card-text= question.question + if question.answers.length > 0 + h5.card-title Réponses + each answer in question.answers + p.card-text Réponse : #{answer.answer} + + if announcement.propertyStatus == 'Disponible' + form(action=`/announcements/${announcement._id}/ask`, method="post") + .form-group.mt-3 + label(for="question") Poser une question + input#question.form-control(type="text", name="question", required) + .mt-3 + button.btn.btn-primary(type="submit") Poser la question + + if user && user.isAgent && announcement.questions.length > 0 + h2.card-title.mb-4 Questions et Réponses + each question in announcement.questions + .card.mb-3 + .card-body + h5.card-title Question de #{question.user} + p.card-text Question : #{question.question} + each answer in question.answers + h5.card-title Réponse + p.card-text Réponse : #{answer.answer} + + form(action=`/announcements/${announcement._id}/question/${question._id}/answer`, method="post") + .form-group.mt-3 + label(for="answer") Répondre + input#answer.form-control(type="text", name="answer", required) + .mt-3 + button.btn.btn-primary(type="submit") Répondre + diff --git a/views/announcements.pug b/views/announcements.pug index 685609f..d0f5935 100644 --- a/views/announcements.pug +++ b/views/announcements.pug @@ -11,12 +11,26 @@ block content a.btn.btn-danger(href="/logout") Déconnexion .row - each announcement in announcements - .col-md-4.mb-4 - .card - img.card-img-top(src=`/uploads/${announcement.photos[0]}`, alt=announcement.title) - .card-body - h5.card-title= announcement.title - p.card-text= announcement.propertyType - p.card-text= announcement.price + '€' - a.btn.btn-primary(href=`/announcements/${announcement._id}`) Voir les détails + if user && user.isAgent + each announcement in announcements + if announcement.userName == user.username + .col-md-4.mb-4 + .card + img.card-img-top(src=`/uploads/${announcement.photos[0]}`, alt=announcement.title) + .card-body + h5.card-title= announcement.title + p.card-text= announcement.propertyType + p.card-text= announcement.price + '€' + a.btn.btn-primary(href=`/announcements/${announcement._id}`) Voir les détails + + else + each announcement in announcements + if announcement.publicationStatus == 'Publiée' + .col-md-4.mb-4 + .card + img.card-img-top(src=`/uploads/${announcement.photos[0]}`, alt=announcement.title) + .card-body + h5.card-title= announcement.title + p.card-text= announcement.propertyType + p.card-text= announcement.price + '€' + a.btn.btn-primary(href=`/announcements/${announcement._id}`) Voir les détails \ No newline at end of file -- GitLab