From e2ae466155fa060d4ffade592548c4e0f2aa6ab6 Mon Sep 17 00:00:00 2001 From: Katharyn Lynn Oggenfuss Date: Fri, 19 Mar 2021 09:01:07 -0400 Subject: [PATCH] Final commit --- Dunder-Mifflin-Model.js | 26 +++++ controllers/employees.js | 110 +++++++++++++++++++ controllers/temp-bootcamp.js | 200 +++++++++++++++++++++++++++++++++++ middleware/async.js | 4 + 4 files changed, 340 insertions(+) create mode 100644 Dunder-Mifflin-Model.js create mode 100644 controllers/employees.js create mode 100644 controllers/temp-bootcamp.js create mode 100644 middleware/async.js diff --git a/Dunder-Mifflin-Model.js b/Dunder-Mifflin-Model.js new file mode 100644 index 0000000..fc95349 --- /dev/null +++ b/Dunder-Mifflin-Model.js @@ -0,0 +1,26 @@ +//Models are defined through the Schema interface. +const mongoose = require("mongoose"); + +const Schema = mongoose.Schema; +const ObjectId = Schema.ObjectId; + +const Employee = new Schema({ + id :number, + name: string, + title: string, + department: Department, + salary: number, + manager: string +}); + +const Department = new Schema({ + Department: [ + SALES, + CORPORATE, + ACCOUNTING, + RECEPTION, + HUMANRESOURCES + ] +}); + +modules.export = mongoose.model("Employee, EmployeeDetails"); diff --git a/controllers/employees.js b/controllers/employees.js new file mode 100644 index 0000000..9fe3d63 --- /dev/null +++ b/controllers/employees.js @@ -0,0 +1,110 @@ + +const ErrorResponse = require('../utils/errorResponse'); +const asyncHandler = require('../middleware/async'); +const Employee = require('../models/Dunder-Mifflin-Model'); + +// CRUD +// GET, POST, PUT, DELETE Employee by id + + +// @desc Get single employee +// @route GET /api/v1/employees/:id +// @access Public +exports.Employee = asyncHandler(async (req, res, next) => { + const employee = await Employee.findById(req.params.id); + + if (!employee) { + return next( + new ErrorResponse(`Employee not found with id of ${req.params.id}`, 404) + ); + } + + res.status(200).json({ success: true, data: employee }); + }); + +// @desc Create new employee +// @route POST /api/v1/employees +// @access Private +exports.createEmployee = asyncHandler(async (req, res, next) => { + // Add user to req,body + req.body.user = req.user.id; + + // Check for employee + const employeeAlreadyExists = await Employee.findOne({ user: req.user.id }); +}); + // If the user is not an admin or if employee exists, they can't add an employee + if (employeeAlreadyExists || req.user.role !== 'admin') { + return next( + new ErrorResponse( + `The user with ID ${req.user.id} does not have permission to create an employee, or employee already exists`, + 400 + ) + ); + } + + const employee = await Employee.create(req.body); + + res.status(201).json({ + success: true, + data: employee + }); + + +// @desc Update Employee +// @route PUT /api/v1/employees/:id +// @access Private +exports.updateEmployees = asyncHandler(async (req, res, next) => { + let employee = await Employee.findById(req.params.id); + + if (!employee) { + return next( + new ErrorResponse(`Employee not found with id of ${req.params.id}`, 404) + ); + } + + // Make sure user is admin and verify user permissions + if (employee.user.toString() !== req.user.id && req.user.role === 'admin') { + return next( + new ErrorResponse( + `User ${req.user.id} is not authorized to update this employee`, + 401 + ) + ); + } + + employee = await Employee.findByIdAndUpdate(req.params.id, req.body, { + new: true, + runValidators: true + }); + + res.status(200).json({ success: true, data: employee }); + }); + +// @desc Delete employee +// @route DELETE /api/v1/employee/:id +// @access Private +exports.deleteEmployee = asyncHandler(async (req, res, next) => { + const employee = await Employee.findById(req.params.id); + + if (!employee) { + return next( + new ErrorResponse(`Employee not found with id of ${req.params.id}`, 404) + ); + } + + // Make sure employee exists and user is admin + if (employee.user.toString() !== req.user.id && req.user.role !== 'admin') { + return next( + new ErrorResponse( + `User ${req.user.id} is not authorized to delete this employee`, + 401 + ) + ); + } + + await employee.remove(); + + res.status(200).json({ success: true, data: {} }); + }); + + diff --git a/controllers/temp-bootcamp.js b/controllers/temp-bootcamp.js new file mode 100644 index 0000000..90a8fe7 --- /dev/null +++ b/controllers/temp-bootcamp.js @@ -0,0 +1,200 @@ +const path = require('path'); +const ErrorResponse = require('../utils/errorResponse'); +const asyncHandler = require('../middleware/async'); +const geocoder = require('../utils/geocoder'); +const Bootcamp = require('../models/Bootcamp'); + +// @desc Get all bootcamps +// @route GET /api/v1/bootcamps +// @access Public +exports.getBootcamps = asyncHandler(async (req, res, next) => { + res.status(200).json(res.advancedResults); +}); + +// @desc Get single bootcamp +// @route GET /api/v1/bootcamps/:id +// @access Public +exports.getBootcamp = asyncHandler(async (req, res, next) => { + const bootcamp = await Bootcamp.findById(req.params.id); + + if (!bootcamp) { + return next( + new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404) + ); + } + + res.status(200).json({ success: true, data: bootcamp }); +}); + +// @desc Create new bootcamp +// @route POST /api/v1/bootcamps +// @access Private +exports.createBootcamp = asyncHandler(async (req, res, next) => { + // Add user to req,body + req.body.user = req.user.id; + + // Check for published bootcamp + const publishedBootcamp = await Bootcamp.findOne({ user: req.user.id }); + + // If the user is not an admin, they can only add one bootcamp + if (publishedBootcamp && req.user.role !== 'admin') { + return next( + new ErrorResponse( + `The user with ID ${req.user.id} has already published a bootcamp`, + 400 + ) + ); + } + + const bootcamp = await Bootcamp.create(req.body); + + res.status(201).json({ + success: true, + data: bootcamp + }); +}); + +// @desc Update bootcamp +// @route PUT /api/v1/bootcamps/:id +// @access Private +exports.updateBootcamp = asyncHandler(async (req, res, next) => { + let bootcamp = await Bootcamp.findById(req.params.id); + + if (!bootcamp) { + return next( + new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404) + ); + } + + // Make sure user is bootcamp owner + if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { + return next( + new ErrorResponse( + `User ${req.user.id} is not authorized to update this bootcamp`, + 401 + ) + ); + } + + bootcamp = await Bootcamp.findByIdAndUpdate(req.params.id, req.body, { + new: true, + runValidators: true + }); + + res.status(200).json({ success: true, data: bootcamp }); +}); + +// @desc Delete bootcamp +// @route DELETE /api/v1/bootcamps/:id +// @access Private +exports.deleteBootcamp = asyncHandler(async (req, res, next) => { + const bootcamp = await Bootcamp.findById(req.params.id); + + if (!bootcamp) { + return next( + new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404) + ); + } + + // Make sure user is bootcamp owner + if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { + return next( + new ErrorResponse( + `User ${req.user.id} is not authorized to delete this bootcamp`, + 401 + ) + ); + } + + await bootcamp.remove(); + + res.status(200).json({ success: true, data: {} }); +}); + +// @desc Get bootcamps within a radius +// @route GET /api/v1/bootcamps/radius/:zipcode/:distance +// @access Private +exports.getBootcampsInRadius = asyncHandler(async (req, res, next) => { + const { zipcode, distance } = req.params; + + // Get lat/lng from geocoder + const loc = await geocoder.geocode(zipcode); + const lat = loc[0].latitude; + const lng = loc[0].longitude; + + // Calc radius using radians + // Divide dist by radius of Earth + // Earth Radius = 3,963 mi / 6,378 km + const radius = distance / 3963; + + const bootcamps = await Bootcamp.find({ + location: { $geoWithin: { $centerSphere: [[lng, lat], radius] } } + }); + + res.status(200).json({ + success: true, + count: bootcamps.length, + data: bootcamps + }); +}); + +// @desc Upload photo for bootcamp +// @route PUT /api/v1/bootcamps/:id/photo +// @access Private +exports.bootcampPhotoUpload = asyncHandler(async (req, res, next) => { + const bootcamp = await Bootcamp.findById(req.params.id); + + if (!bootcamp) { + return next( + new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404) + ); + } + + // Make sure user is bootcamp owner + if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') { + return next( + new ErrorResponse( + `User ${req.user.id} is not authorized to update this bootcamp`, + 401 + ) + ); + } + + if (!req.files) { + return next(new ErrorResponse(`Please upload a file`, 400)); + } + + const file = req.files.file; + + // Make sure the image is a photo + if (!file.mimetype.startsWith('image')) { + return next(new ErrorResponse(`Please upload an image file`, 400)); + } + + // Check filesize + if (file.size > process.env.MAX_FILE_UPLOAD) { + return next( + new ErrorResponse( + `Please upload an image less than ${process.env.MAX_FILE_UPLOAD}`, + 400 + ) + ); + } + + // Create custom filename + file.name = `photo_${bootcamp._id}${path.parse(file.name).ext}`; + + file.mv(`${process.env.FILE_UPLOAD_PATH}/${file.name}`, async err => { + if (err) { + console.error(err); + return next(new ErrorResponse(`Problem with file upload`, 500)); + } + + await Bootcamp.findByIdAndUpdate(req.params.id, { photo: file.name }); + + res.status(200).json({ + success: true, + data: file.name + }); + }); +}); diff --git a/middleware/async.js b/middleware/async.js new file mode 100644 index 0000000..ed0d25a --- /dev/null +++ b/middleware/async.js @@ -0,0 +1,4 @@ +const asyncHandler = fn => (req, res, next) => + Promise.resolve(fn(req, res, next)).catch(next); + +module.exports = asyncHandler;