diff --git a/app.js b/app.js index c33af603..25934340 100644 --- a/app.js +++ b/app.js @@ -62,12 +62,15 @@ app.use(flash()); //locals app.use(function(req, res, next) { - res.locals.success = req.flash('success'); - res.locals.emailError = req.flash('emailError'); - res.locals.errors = req.flash('errors'); - next(); + res.locals.success = req.flash('success'); + res.locals.emailError = req.flash('emailError'); + res.locals.errors = req.flash('errors'); + res.locals.paymentError = req.flash('paymentError'); + res.locals.payment = req.flash('payment'); + next(); }); + app.use('/', indexRouter); // app.use('/users', usersRouter); diff --git a/config/paystack.js b/config/paystack.js new file mode 100644 index 00000000..387f2c9b --- /dev/null +++ b/config/paystack.js @@ -0,0 +1,22 @@ +const paystack = request => { + const PAYSTACK_SECRET_KEY = `Bearer ${process.env.PAYSTACK_SECRET_KEY}`; + + const verifyPayment = (ref, mycallback) => { + const options = { + url: 'https://api.paystack.co/transaction/verify/' + encodeURIComponent(ref), + headers: { + authorization: PAYSTACK_SECRET_KEY, + 'content-type': 'application/json', + 'cache-control': 'no-cache', + }, + }; + const callback = (error, response, body) => { + return mycallback(error, body); + }; + request(options, callback); + }; + + return { verifyPayment }; +}; + +module.exports = paystack; diff --git a/controllers/admin.js b/controllers/admin.js new file mode 100644 index 00000000..a9981789 --- /dev/null +++ b/controllers/admin.js @@ -0,0 +1,277 @@ +const Subscribe = require('./promise').Subscribe; +const Agent1 = require('./promise').AgentDb; +const request = require('request'); +const _ = require('lodash'); +const validateAgentQueryText = require('../validation/agent'); +const Payment = require('../models/payment'); +const { verifyPayment } = require('../config/paystack')(request); +const Home = require('../controllers/home'); + +const Subscription = { + async viewAllEmailSubscribers(req, res) { + try { + let Subscribers = await Subscribe.find(); + return res.status(200).json({ + dataCount: Object.keys(Subscribers).length, + data: Subscribers, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async viewOneEmailSubscriber(req, res) { + const { _id } = req.params; + + try { + let Subscribers = await Subscribe.findOne({_id}); + return res.status(200).json({ + data: Subscribers, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async DeleteOneEmailSubscriber(req, res) { + const { _id } = req.params; + try { + let Subscribers = await Subscribe.findOneAndDelete({_id}); + return res.status(200).json({ + data: `${Subscribers.email} successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async DeleteAllEmailSubscribers(req, res) { + try { + await Subscribe.drop(); + return res.status(200).json({ + data: `All subscribers successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async create_agent(req, res) { + const { errors, isValid } = validateAgentQueryText(req.body); + + // Check Validation + if (!isValid) { + return res.status(400).json(errors); + } + + const queryText = { + first_name: req.body.first_name, + last_name: req.body.last_name, + email: req.body.email, + phone_number: req.body.phone_number, + rate: 0, + totalRate: 0, + totalPeople: 0, + }; + try { + let createdAgent = await Agent1.create(queryText); + return res.status(200).json({ + status: 'success', + message: createdAgent, + }); + } catch (error) { + return res.status(500).send(error); + } + }, + + async rateAnAgent(req, res) { + const { _id } = req.params; + const { rate } = req.body; + + try { + let Agent = await Agent1.findOne({ _id: _id }); + if (Agent != undefined) { + const totalRate = parseInt(Agent.totalRate, 10); + const totalPeople = parseInt(Agent.totalPeople, 10); + const rateNumber = parseInt(rate, 10); + + const newTotalRate = totalRate + rateNumber; + const presentTotalPeople = totalPeople + 1; + const presentRate = newTotalRate / presentTotalPeople; + const presentRate1 = Math.round(presentRate); + + const data = { + first_name: Agent.first_name, + last_name: Agent.last_name, + email: Agent.email, + phone_number: Agent.phone_number, + rate: presentRate1, + totalRate: newTotalRate, + totalPeople: presentTotalPeople, + }; + await Agent1.findOneAndUpdate(Agent._id, data); + return res.status(200).json({ + status: 'success', + message: 'Thank you for your rating', + }); + } else { + return res.status(400).json({ + status: 'error', + message: `Such agent does not exist`, + }); + } + } catch (error) { + return res.status(500).json(error); + } + }, + + async get_all_agents(req, res) { + try { + let Agents = await Agent1.find(); + return res.status(200).json({ + dataCount: Object.keys(Agents).length, + data: Agents, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async get_one_agent(req, res) { + const { _id } = req.params; + try { + let AgentOne = await Agent1.findOne({_id}); + return res.status(200).json({ + data: AgentOne, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async DeleteOneAgent(req, res) { + const { _id } = req.params; + try { + let Agnt = await Agent1.findOneAndDelete({ _id: _id }); + return res.status(200).json({ + data: `${Agnt.first_name} ${Agnt.last_name} successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async DeleteAllAgents(req, res) { + try { + // await Agent1.remove(); + await Agent1.drop(); + return res.status(200).json({ + data: `All agents successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async savePayment(req, res) { + const ref = req.query.reference; + verifyPayment(ref, (error, body) => { + if (error) { + req.flash('paymentError', 'Payment not successful, Something went wrong'); + return res.redirect('/'); + } + response = JSON.parse(body); + + const data = _.at(response.data, ['reference', 'amount', 'customer.email']); + + [reference, amount, email] = data; + created_At = new Date(); + + newPayment = { reference, amount, email, created_At }; + + const payment = new Payment(newPayment); + + payment + .save() + .then(payment => { + if (!payment) { + return res.status(500).json({ + status: 'no payment made', + message: 'error', + }); + } + res.redirect('/receipt/' + payment._id); + }) + .catch(error => { + return res.status(500).json(error); + }); + }); + }, + + async redirect(req, res) { + const id = req.params.id; + Payment.findById(id) + .then(payment => { + if (!payment) { + req.flash('paymentError', 'Payment not successful'); + return res.redirect('/'); + } else { + req.flash('payment', 'Payment successful, Please kindly fill the form below to continue'); + return res.redirect('/applicant'); + } + }) + .catch(e => { + return res.status(500).json(e); + }); + }, + + async view_all_payments(req, res) { + try { + let Payments = await Payment.find(); + return res.status(200).json({ + dataCount: Object.keys(Payments).length, + data: Payments, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async view_one_payment(req, res) { + const { _id } = req.params; + try { + let Payment1 = await Payment.findOne({_id}); + return res.status(200).json({ + data: Payment1, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async deleteOnePayment(req, res) { + const { _id } = req.params; + try { + let Payment1 = await Payment.findOneAndDelete({ _id: _id }); + return res.status(200).json({ + data: `${Payment1.email} and related data successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, + + async deleteAllPayments(req, res) { + try { + // await Payment.remove(); + await Payment.drop(); + return res.status(200).json({ + data: `All payments successfully deleted`, + }); + } catch (error) { + return res.status(500).json(error); + } + }, +}; + +module.exports = Subscription; diff --git a/controllers/promise.js b/controllers/promise.js index 1947a304..b8d77cfc 100644 --- a/controllers/promise.js +++ b/controllers/promise.js @@ -1,135 +1,330 @@ const Jobs = require('../models/jobs'); const Users = require('../models/user'); -const Agent = require('../models/agent'); +// const Agent = require('../models/agent'); +const NewAgent = require('../models/newAgent'); const Applicant = require('../models/applicant'); class Db { - /** - * @param {string} text - * @returns {object} Return all - */ - static find(param) { - return new Promise((resolve, reject) => { - Jobs.find(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static findOne(param) { - return new Promise((resolve, reject) => { - Jobs.findOne(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static findOneAndUpdate(param, text) { - return new Promise((resolve, reject) => { - Jobs.findOneAndUpdate(param, text) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static findOneAndDelete(param) { - return new Promise((resolve, reject) => { - Jobs.findOneAndDelete(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static create(param) { - return new Promise((resolve, reject) => { - Jobs.create(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } + /** + * @param {string} text + * @returns {object} Return all + */ + static find(param) { + return new Promise((resolve, reject) => { + Jobs.find(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOne(param) { + return new Promise((resolve, reject) => { + Jobs.findOne(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndUpdate(param, text) { + return new Promise((resolve, reject) => { + Jobs.findOneAndUpdate(param, text) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndDelete(param) { + return new Promise((resolve, reject) => { + Jobs.findOneAndDelete(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static create(param) { + return new Promise((resolve, reject) => { + Jobs.create(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } - static insertMany(param) { - return new Promise((resolve, reject) => { - Jobs.insertMany(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static countDocuments(param) { - return new Promise((resolve, reject) => { - Jobs.countDocuments(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } + static insertMany(param) { + return new Promise((resolve, reject) => { + Jobs.insertMany(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static countDocuments(param) { + return new Promise((resolve, reject) => { + Jobs.countDocuments(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } } class DbApplicant { - /** - * @param {string} text - * @returns {object} Return all - */ - static find(param) { - return new Promise((resolve, reject) => { - Applicant.find(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } - static create(param) { - return new Promise((resolve, reject) => { - Applicant.create(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } + /** + * @param {string} text + * @returns {object} Return all + */ + static find(param) { + return new Promise((resolve, reject) => { + Applicant.find(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static create(param) { + return new Promise((resolve, reject) => { + Applicant.create(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } - static findOneAndDelete(param) { - return new Promise((resolve, reject) => { - Applicant.findOneAndDelete(param) - .then(res => { - resolve(res); - }) - .catch(err => { - reject(err); - }); - }); - } + static findOneAndDelete(param) { + return new Promise((resolve, reject) => { + Applicant.findOneAndDelete(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } +} + +class Subscribe { + /** + * @param {string} text + * @returns {object} Return all + */ + static find(param) { + return new Promise((resolve, reject) => { + Users.find(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOne(param) { + return new Promise((resolve, reject) => { + Users.findOne(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndUpdate(param, text) { + return new Promise((resolve, reject) => { + Users.findOneAndUpdate(param, text) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndDelete(param) { + return new Promise((resolve, reject) => { + Users.findOneAndDelete(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static create(param) { + return new Promise((resolve, reject) => { + Users.create(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + + static insertMany(param) { + return new Promise((resolve, reject) => { + Users.insertMany(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static countDocuments(param) { + return new Promise((resolve, reject) => { + Users.countDocuments(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static drop(param) { + return new Promise((resolve, reject) => { + Users.drop(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } +} + +class AgentDb { + /** + * @param {string} text + * @returns {object} Return all + */ + static find(param) { + return new Promise((resolve, reject) => { + NewAgent.find(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOne(param) { + return new Promise((resolve, reject) => { + NewAgent.findOne(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndUpdate(param, text) { + return new Promise((resolve, reject) => { + NewAgent.findOneAndUpdate(param, text) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static findOneAndDelete(param) { + return new Promise((resolve, reject) => { + NewAgent.findOneAndDelete(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static create(param) { + return new Promise((resolve, reject) => { + NewAgent.create(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + + static insertMany(param) { + return new Promise((resolve, reject) => { + NewAgent.insertMany(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static countDocuments(param) { + return new Promise((resolve, reject) => { + NewAgent.countDocuments(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } + static drop(param) { + return new Promise((resolve, reject) => { + NewAgent.drop(param) + .then(res => { + resolve(res); + }) + .catch(err => { + reject(err); + }); + }); + } } module.exports = { - Db, - DbApplicant + Db, + DbApplicant, + Subscribe, + AgentDb, }; diff --git a/models/newAgent.js b/models/newAgent.js new file mode 100644 index 00000000..4cb38009 --- /dev/null +++ b/models/newAgent.js @@ -0,0 +1,35 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const agentSchema = new Schema({ + first_name: { + type: String, + required: true, + }, + last_name: { + type: String, + required: true, + }, + email: { + type: String, + required: true, + }, + phone_number: { + type: String, + required: true, + }, + rate: { + type: String, + required: false, + }, + totalRate: { + type: String, + required: false, + }, + totalPeople: { + type: String, + required: false, + }, +}); + +module.exports = mongoose.model('NewAgent', agentSchema); diff --git a/models/payment.js b/models/payment.js new file mode 100644 index 00000000..bd475054 --- /dev/null +++ b/models/payment.js @@ -0,0 +1,23 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const paymentSchema = new Schema({ + email: { + type: String, + required: true, + }, + amount: { + type: String, + required: true, + }, + reference: { + type: String, + required: true, + }, + created_At: { + type: String, + required: true, + }, +}); + +module.exports = mongoose.model('Payment', paymentSchema); diff --git a/routes/index.js b/routes/index.js index 19dc9843..2692a266 100644 --- a/routes/index.js +++ b/routes/index.js @@ -9,6 +9,7 @@ const Paystack = require('../controllers/paystack'); var Admin = require('../models/admin'); var JobModel = require('../models/jobs'); const Applicant = require('../controllers/applicant'); +const Subscription = require('../controllers/admin'); const session = require('../controllers/stripe'); //var app = require('passport'); /* GET home page. */ @@ -205,4 +206,21 @@ router.post('/contact', UserController.sendContactAlert); // router.get('/remote-jobs/:job_id', Jobs.update_job); // router.get('/remote-jobs/:job_id', Jobs.cancel_job); + +router.get('/view_all_email_subscribers', Subscription.viewAllEmailSubscribers); +router.get('/view_one_email_subscriber/:_id', Subscription.viewOneEmailSubscriber); +router.get('/delete_one_email_subscriber/:_id', Subscription.DeleteOneEmailSubscriber); +// router.get('/delete_all_email_subscribers', Subscription.DeleteAllEmailSubscribers); //CAUTION, IT'S WORKING +router.post('/create_agent', Subscription.create_agent); +router.post('/rate_an_agent/:_id', Subscription.rateAnAgent); +router.get('/view_all_agents', Subscription.get_all_agents); +router.get('/view_one_agent/:_id', Subscription.get_one_agent); +router.get('/delete_one_agent/:_id', Subscription.DeleteOneAgent); +// router.get('/delete_all_agents', Subscription.DeleteAllAgents); //CAUTION, IT'S WORKING +router.get('/invoice', Subscription.savePayment); +router.get('/receipt/:id', Subscription.redirect); +router.get('/view_all_payments', Subscription.view_all_payments); +router.get('/view_one_payment/:_id', Subscription.view_one_payment); +router.get('/delete_one_payment/:_id', Subscription.deleteOnePayment); +// router.get('/delete_all_payments', Subscription.deleteAllPayments); //CAUTION, IT'S WORKING module.exports = router; diff --git a/validation/agent.js b/validation/agent.js index 1bc39e13..61a44048 100644 --- a/validation/agent.js +++ b/validation/agent.js @@ -2,7 +2,6 @@ var Validator = require('validator'); var isEmpty = require('./is-empty'); - const validateAgentQueryText = data => { const errors = {}; data.first_name = !isEmpty(data.first_name) ? data.first_name : ''; @@ -13,27 +12,18 @@ const validateAgentQueryText = data => { if (Validator.isEmpty(data.first_name)) { errors.first_name = 'First name is required'; } - if (Validator.isAlpha(data.first_name).isLength({ min: 3 }).trim(data.first_name)) { - errors.first_name = 'First name should contain more than three alphabets'; - } if (Validator.isEmpty(data.last_name)) { errors.last_name = 'Last Name is required'; } - if (Validator.isAlpha(data.last_name).isLength({ min: 3 }).trim(data.last_name)) { - errors.last_name = 'Last name should contain more than three alphabets'; - } if (Validator.isEmpty(data.email)) { errors.email = 'Email is required'; } - if (!Validator.isEmail(data.email).normalizeEmail(data.email).trim(data.email)) { - errors.email = 'Email is invalid'; - } if (Validator.isEmpty(data.phone_number)) { errors.phone_number = 'Phone number is required'; } - if (Validator.isMobilePhoneLocales(data.phone_number).trim(data.phone_number)) { - errors.phone_number = 'Phone number is invalid'; - } + // if (Validator.isMobilePhoneLocales(data.phone_number).trim(data.phone_number)) { + // errors.phone_number = 'Phone number is invalid'; + // } return { errors, diff --git a/validation/rateAgent.js b/validation/rateAgent.js new file mode 100644 index 00000000..930c7b14 --- /dev/null +++ b/validation/rateAgent.js @@ -0,0 +1,23 @@ +/* eslint-disable no-param-reassign */ +var Validator = require('validator'); +var isEmpty = require('./is-empty'); + +const validateRateAgent = data => { + const errors = {}; + data.rate = !isEmpty(data.rate) ? data.rate : ''; + + if (Validator.isEmpty(data.rate)) { + errors.rate = 'Rating an agent is required'; + } + + if (!Validator.isLength(data.rate, { min: 1, max: 5})) { + errors.rate = 'Rating must be between 1 to 5 with 5 being the best and 1 the worst'; + } + + return { + errors, + isValid: isEmpty(errors), + }; +}; + +module.exports = validateRateAgent; diff --git a/views/admin_dashboard.hbs b/views/admin_dashboard.hbs index 64744165..da2652cf 100644 --- a/views/admin_dashboard.hbs +++ b/views/admin_dashboard.hbs @@ -132,31 +132,6 @@ - -
-
-
Payment
-
-
- - - - - - - - - - - - - - - - -
S/NPayer's emailPayment Ref No.Payment dateAmount paidTotal No of payment made
-
-
diff --git a/views/manage_jobs.hbs b/views/manage_jobs.hbs index b11a52f0..76327357 100644 --- a/views/manage_jobs.hbs +++ b/views/manage_jobs.hbs @@ -55,7 +55,7 @@

This is the managejobs page for DevAlert

- +
diff --git a/views/partials/header.hbs b/views/partials/header.hbs index 92016dd1..d1eed58c 100644 --- a/views/partials/header.hbs +++ b/views/partials/header.hbs @@ -22,44 +22,73 @@
{{/if}}
+ + +
+ {{#each errors}} + + {{/each}} {{#if paymentError}} +
+ {{paymentError}} + +
+ {{/if}} {{#if payment}} +
+ {{payment}} + +
+ {{/if}} +
+ {{!-- REGISTER MODAL--}} - \ No newline at end of file