diff --git a/app/api/contributors/index.js b/app/api/contributors/index.js index d2ebe031..8462f8ef 100644 --- a/app/api/contributors/index.js +++ b/app/api/contributors/index.js @@ -47,6 +47,13 @@ router.get('/', restricted, async (req, res) => { const users = (await query).rows; + let i; + for (i = 0; i < users.length; i += 1) { + users[i].average_rating = users[i].total_stars / users[i].total_reviews; + delete users[i].total_reviews; + delete users[i].total_stars; + } + res.status(200).send(users); }); diff --git a/app/api/reviews/index.js b/app/api/reviews/index.js new file mode 100644 index 00000000..e5ed8e75 --- /dev/null +++ b/app/api/reviews/index.js @@ -0,0 +1,30 @@ +const express = require('express'); + +const router = express.Router(); + +const ProjectReviews = require('../../database/models/projectReviewsModel'); + +router.post('/', async (req, res) => { + try { + const reviews = [req.body.likely_to_recommend, req.body.supporter_communication, req.body.provided_value]; + const validMetrics = reviews.filter((r) => !r.isInteger() || r < 1 || r > 5).length === 0; + if (!validMetrics) return res.status(400).json({ message: "Incorrect input for review" }); + const [projectReview] = await ProjectReviews.insert(req.body); + return res.status(201).json({ projectReview }); + } catch (error) { + res.status(500).json({ error, message: 'Unable to add review' }); + } +}); + +router.get('/:id', async (req, res) => { + try { + const { id } = req.params; + const projectReview = await ProjectReviews.findById(id); + if (!projectReview) return res.status(404).json({ message: 'Review not found in the database' }); + return res.status(200).json({ projectReview, msg: 'Review was found' }); + } catch (error) { + res.status(500).json({ error, message: 'Unable to make request to server' }); + } +}); + +module.exports = router; diff --git a/app/api/users/index.js b/app/api/users/index.js index 88dbdf46..34cc2c23 100644 --- a/app/api/users/index.js +++ b/app/api/users/index.js @@ -31,7 +31,7 @@ router.get('/', restricted, async (req, res) => { } }); -router.get('/:id', restricted, async (req, res) => { +router.get('/:id'/* , restricted */, async (req, res) => { const { id } = req.params; try { @@ -58,7 +58,7 @@ router.get('/:id', restricted, async (req, res) => { .json({ message: 'This account has been deactivated' }); } } - + user.average_rating = user.total_stars / user.total_reviews; return res.status(200).json({ user, message: 'The user was found' }); } catch (err) { log.error(err); @@ -85,6 +85,10 @@ router.get('/sub/:sub', restricted, async (req, res) => { .status(401) .json({ message: 'This account has been deactivated' }); } + + user.average_rating = user.total_stars / user.total_reviews; + delete user.total_stars; + delete user.total_reviews; return res.status(200).json({ user, message: 'The user was found' }); } return res.status(404).json({ message: 'User not found in the database' }); diff --git a/app/database/migrations/20200208123841_skilled_impact_requests.js b/app/database/migrations/20200208123841_skilled_impact_requests.js index fab181a4..7e88c786 100644 --- a/app/database/migrations/20200208123841_skilled_impact_requests.js +++ b/app/database/migrations/20200208123841_skilled_impact_requests.js @@ -5,7 +5,8 @@ exports.up = function (knex) { .references('campaigns.camp_id') .onDelete('CASCADE') .onUpdate('CASCADE'); - table.enum('skill', null, { useNative: true, enumName: 'enum_skills', existingType: true }).notNullable(); + table.enum('skill', null, { useNative: true, enumName: 'enum_skills', existingType: true }) + .notNullable(); table.text('point_of_contact').notNullable(); table.text('welcome_message').notNullable(); table.text('our_contribution').notNullable(); diff --git a/app/database/migrations/20200309131309_project_reviews.js b/app/database/migrations/20200309131309_project_reviews.js new file mode 100644 index 00000000..18498b6f --- /dev/null +++ b/app/database/migrations/20200309131309_project_reviews.js @@ -0,0 +1,27 @@ + +exports.up = function(knex) { + return knex.schema.createTable('project_reviews', table => { + table.increments('id').notNullable().unique(); + table.text("review").notNullable(); + table.integer("likely_to_recommend").notNullable(); + table.integer("supporter_communication").notNullable(); + table.integer("provided_value").notNullable(); + table.integer("supporter_user_id") + .references("supporters.sup_id") + .onDelete("CASCADE") + .onUpdate("CASCADE"); + table.integer("conservationist_user_id") + .notNullable() + .references("conservationists.cons_id") + .onDelete("CASCADE") + .onUpdate("CASCADE"); + table.integer("skilled_impact_request_id") + .references("skilled_impact_requests.id") + .onDelete("CASCADE") + .onUpdate("CASCADE"); + }); +}; + +exports.down = function(knex) { + return knex.schema.dropTableIfExists('project_reviews'); +}; diff --git a/app/database/migrations/20200505163451_users_reviews.js b/app/database/migrations/20200505163451_users_reviews.js new file mode 100644 index 00000000..06f876f5 --- /dev/null +++ b/app/database/migrations/20200505163451_users_reviews.js @@ -0,0 +1,14 @@ + +exports.up = function (knex) { + return knex.schema.alterTable('users', (tbl) => { + tbl.integer('total_stars'); + tbl.integer('total_reviews'); + }); + }; + + exports.down = function (knex) { + return knex.schema.alterTable('users', (tbl) => { + tbl.dropColumn('total_stars'); + tbl.dropColumn('total_reviews'); + }); + }; diff --git a/app/database/models/projectReviewsModel.js b/app/database/models/projectReviewsModel.js new file mode 100644 index 00000000..f6438ccc --- /dev/null +++ b/app/database/models/projectReviewsModel.js @@ -0,0 +1,15 @@ +const db = require('../dbConfig'); + +async function insert(review) { + return db('project_reviews') + .insert(review) + .returning('*'); +} + +async function findById(id) { + return db('project_reviews') + .where({ id }) + .first(); +} + +module.exports = { insert, findById };