diff --git a/_data/bootcamps.json b/_data/bootcamps.json new file mode 100644 index 0000000..c117ee8 --- /dev/null +++ b/_data/bootcamps.json @@ -0,0 +1,67 @@ +[ + { + "_id": "5d713995b721c3bb38c1f5d0", + "user": "5d7a514b5d2c12c7449be045", + "name": "Devworks Bootcamp", + "description": "Devworks is a full stack JavaScript Bootcamp located in the heart of Boston that focuses on the technologies you need to get a high paying job as a web developer", + "website": "https://devworks.com", + "phone": "(111) 111-1111", + "email": "enroll@devworks.com", + "address": "233 Bay State Rd Boston MA 02215", + "careers": ["Web Development", "UI/UX", "Business"], + "housing": true, + "jobAssistance": true, + "jobGuarantee": false, + "acceptGi": true + }, + { + "_id": "5d713a66ec8f2b88b8f830b8", + "user": "5d7a514b5d2c12c7449be046", + "name": "ModernTech Bootcamp", + "description": "ModernTech has one goal, and that is to make you a rockstar developer and/or designer with a six figure salary. We teach both development and UI/UX", + "website": "https://moderntech.com", + "phone": "(222) 222-2222", + "email": "enroll@moderntech.com", + "address": "220 Pawtucket St, Lowell, MA 01854", + "careers": ["Web Development", "UI/UX", "Mobile Development"], + "housing": false, + "jobAssistance": true, + "jobGuarantee": false, + "acceptGi": true + }, + { + "_id": "5d725a037b292f5f8ceff787", + "user": "5c8a1d5b0190b214360dc031", + "name": "Codemasters", + "description": "Is coding your passion? Codemasters will give you the skills and the tools to become the best developer possible. We specialize in full stack web development and data science", + "website": "https://codemasters.com", + "phone": "(333) 333-3333", + "email": "enroll@codemasters.com", + "address": "85 South Prospect Street Burlington VT 05405", + "careers": ["Web Development", "Data Science", "Business"], + "housing": false, + "jobAssistance": false, + "jobGuarantee": false, + "acceptGi": false + }, + { + "_id": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc032", + "name": "Devcentral Bootcamp", + "description": "Is coding your passion? Codemasters will give you the skills and the tools to become the best developer possible. We specialize in front end and full stack web development", + "website": "https://devcentral.com", + "phone": "(444) 444-4444", + "email": "enroll@devcentral.com", + "address": "45 Upper College Rd Kingston RI 02881", + "careers": [ + "Mobile Development", + "Web Development", + "Data Science", + "Business" + ], + "housing": false, + "jobAssistance": true, + "jobGuarantee": true, + "acceptGi": true + } +] diff --git a/_data/courses.json b/_data/courses.json new file mode 100644 index 0000000..9da3d9b --- /dev/null +++ b/_data/courses.json @@ -0,0 +1,101 @@ +[ + { + "_id": "5d725a4a7b292f5f8ceff789", + "title": "Front End Web Development", + "description": "This course will provide you with all of the essentials to become a successful frontend web developer. You will learn to master HTML, CSS and front end JavaScript, along with tools like Git, VSCode and front end frameworks like Vue", + "weeks": 8, + "tuition": 8000, + "minimumSkill": "beginner", + "scholarhipsAvailable": true, + "bootcamp": "5d713995b721c3bb38c1f5d0", + "user": "5d7a514b5d2c12c7449be045" + }, + { + "_id": "5d725c84c4ded7bcb480eaa0", + "title": "Full Stack Web Development", + "description": "In this course you will learn full stack web development, first learning all about the frontend with HTML/CSS/JS/Vue and then the backend with Node.js/Express/MongoDB", + "weeks": 12, + "tuition": 10000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": true, + "bootcamp": "5d713995b721c3bb38c1f5d0", + "user": "5d7a514b5d2c12c7449be045" + }, + { + "_id": "5d725cb9c4ded7bcb480eaa1", + "title": "Full Stack Web Dev", + "description": "In this course you will learn all about the front end with HTML, CSS and JavaScript. You will master tools like Git and Webpack and also learn C# and ASP.NET with Postgres", + "weeks": 10, + "tuition": 12000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": true, + "bootcamp": "5d713a66ec8f2b88b8f830b8", + "user": "5d7a514b5d2c12c7449be046" + }, + { + "_id": "5d725cd2c4ded7bcb480eaa2", + "title": "UI/UX", + "description": "In this course you will learn to create beautiful interfaces. It is a mix of design and development to create modern user experiences on both web and mobile", + "weeks": 12, + "tuition": 10000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": true, + "bootcamp": "5d713a66ec8f2b88b8f830b8", + "user": "5d7a514b5d2c12c7449be046" + }, + { + "_id": "5d725ce8c4ded7bcb480eaa3", + "title": "Web Design & Development", + "description": "Get started building websites and web apps with HTML/CSS/JavaScript/PHP. We teach you", + "weeks": 10, + "tuition": 12000, + "minimumSkill": "beginner", + "scholarhipsAvailable": true, + "bootcamp": "5d725a037b292f5f8ceff787", + "user": "5c8a1d5b0190b214360dc031" + }, + { + "_id": "5d725cfec4ded7bcb480eaa4", + "title": "Data Science Program", + "description": "In this course you will learn Python for data science, machine learning and big data tools", + "weeks": 10, + "tuition": 9000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": false, + "bootcamp": "5d725a037b292f5f8ceff787", + "user": "5c8a1d5b0190b214360dc031" + }, + { + "_id": "5d725cfec4ded7bcb480eaa5", + "title": "Web Development", + "description": "This course will teach you how to build high quality web applications with technologies like React, Node.js, PHP & Laravel", + "weeks": 8, + "tuition": 8000, + "minimumSkill": "beginner", + "scholarhipsAvailable": false, + "bootcamp": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc032" + }, + { + "_id": "5d725cfec4ded7bcb480eaa6", + "title": "Software QA", + "description": "This course will teach you everything you need to know about quality assurance", + "weeks": 6, + "tuition": 5000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": false, + "bootcamp": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc032" + }, + { + "_id": "5d725cfec4ded7bcb480eaa7", + "title": "IOS Development", + "description": "Get started building mobile applications for IOS using Swift and other tools", + "weeks": 8, + "tuition": 6000, + "minimumSkill": "intermediate", + "scholarhipsAvailable": false, + "bootcamp": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc032" + } +] diff --git a/_data/reviews.json b/_data/reviews.json new file mode 100644 index 0000000..5857728 --- /dev/null +++ b/_data/reviews.json @@ -0,0 +1,66 @@ +[ + { + "_id": "5d7a514b5d2c12c7449be020", + "title": "Learned a ton!", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "8", + "bootcamp": "5d713995b721c3bb38c1f5d0", + "user": "5c8a1d5b0190b214360dc033" + }, + { + "_id": "5d7a514b5d2c12c7449be021", + "title": "Great bootcamp", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "10", + "bootcamp": "5d713995b721c3bb38c1f5d0", + "user": "5c8a1d5b0190b214360dc034" + }, + { + "_id": "5d7a514b5d2c12c7449be022", + "title": "Got me a developer job", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "7", + "bootcamp": "5d713a66ec8f2b88b8f830b8", + "user": "5c8a1d5b0190b214360dc035" + }, + { + "_id": "5d7a514b5d2c12c7449be023", + "title": "Not that great", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "4", + "bootcamp": "5d713a66ec8f2b88b8f830b8", + "user": "5c8a1d5b0190b214360dc036" + }, + { + "_id": "5d7a514b5d2c12c7449be024", + "title": "Great overall experience", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "7", + "bootcamp": "5d725a037b292f5f8ceff787", + "user": "5c8a1d5b0190b214360dc037" + }, + { + "_id": "5d7a514b5d2c12c7449be025", + "title": "Not worth the money", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "5", + "bootcamp": "5d725a037b292f5f8ceff787", + "user": "5c8a1d5b0190b214360dc038" + }, + { + "_id": "5d7a514b5d2c12c7449be026", + "title": "Best instructors", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "10", + "bootcamp": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc039" + }, + { + "_id": "5d7a514b5d2c12c7449be027", + "title": "Was worth the investment", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra feugiat mauris id viverra. Duis luctus ex sed facilisis ultrices. Curabitur scelerisque bibendum ligula, quis condimentum libero fermentum in. Aenean erat erat, aliquam in purus a, rhoncus hendrerit tellus. Donec accumsan justo in felis consequat sollicitudin. Fusce luctus mattis nunc vitae maximus. Curabitur semper felis eu magna laoreet scelerisque", + "rating": "7", + "bootcamp": "5d725a1b7b292f5f8ceff788", + "user": "5c8a1d5b0190b214360dc040" + } +] diff --git a/_data/users.json b/_data/users.json new file mode 100644 index 0000000..0518240 --- /dev/null +++ b/_data/users.json @@ -0,0 +1,107 @@ +[ + { + "_id": "5d7a514b5d2c12c7449be042", + "name": "Admin Account", + "email": "admin@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5d7a514b5d2c12c7449be043", + "name": "Publisher Account", + "email": "publisher@gmail.com", + "role": "publisher", + "password": "123456" + }, + { + "_id": "5d7a514b5d2c12c7449be044", + "name": "User Account", + "email": "user@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5d7a514b5d2c12c7449be045", + "name": "John Doe", + "email": "john@gmail.com", + "role": "publisher", + "password": "123456" + }, + { + "_id": "5d7a514b5d2c12c7449be046", + "name": "Kevin Smith", + "email": "kevin@gmail.com", + "role": "publisher", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc031", + "name": "Mary Williams", + "email": "mary@gmail.com", + "role": "publisher", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc032", + "name": "Sasha Ryan", + "email": "sasha@gmail.com", + "role": "publisher", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc033", + "name": "Greg Harris", + "email": "greg@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc034", + "name": "Derek Glover", + "email": "derek@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc035", + "name": "Stephanie Hanson", + "email": "steph@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc036", + "name": "Jerry Wiliams", + "email": "jerry@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc037", + "name": "Maggie Johnson", + "email": "maggie@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc038", + "name": "Barry Dickens", + "email": "barry@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc039", + "name": "Ryan Bolin", + "email": "ryan@gmail.com", + "role": "user", + "password": "123456" + }, + { + "_id": "5c8a1d5b0190b214360dc040", + "name": "Sara Kensing", + "email": "sara@gmail.com", + "role": "user", + "password": "123456" + } +] diff --git a/config/db.js b/config/db.js index 1169db0..2cc93a0 100644 --- a/config/db.js +++ b/config/db.js @@ -8,7 +8,7 @@ const connectDB = async () => { useUnifiedTopology: true }); - console.log(`MongoDB connected: ${conn.connection.host}`); + console.log(`MongoDB connected: ${conn.connection.host}`.cyan.underline.bold); } module.exports = connectDB; \ No newline at end of file diff --git a/controllers/bootcamps.js b/controllers/bootcamps.js index 0f06d1a..b72f871 100644 --- a/controllers/bootcamps.js +++ b/controllers/bootcamps.js @@ -1,34 +1,106 @@ +const { findByIdAndDelete } = require('../models/Bootcamp'); +const Bootcamp = require('../models/Bootcamp'); + +/** + * NOTES + * - Need body parser middleware (in server.js) in order to access "req.body" within these functions + * - Always wrap in trycatch + * - If client sends data that is not in the model, it gets ignored + */ + // @desc Get all bootcamps // @route GET /api/v1/bootcamps // @access Public -exports.getBootcamps = (req, res, next) => { - res.status(200).json({success: true, msg: 'Get all bootcamps'}); +exports.getBootcamps = async (req, res, next) => { + try { + const bootcamps = await Bootcamp.find(); + res.status(200).json({ + success: true, + count: bootcamps.length, + data: bootcamps + }) + } catch (err) { + res.status(400).json({ + success: false + }); + } }; // @desc Get single bootcamps // @route GET /api/v1/bootcamps/:id // @access Public -exports.getBootcamp = (req, res, next) => { - res.status(200).json({success: true, msg: `Get bootcamp ${req.params.id}`}); +exports.getBootcamp = async (req, res, next) => { + try { + const bootcamp = await Bootcamp.findById(req.params.id); + + // handle err if id does not match any bootcamps + if (!bootcamp) return res.status(400).json({success: false}); + + res.status(200).json({ + success: true, + data: bootcamp + }) + } catch (err) { + // handle err if id is not correct format (ie. # of digits) + + // res.status(400).json({ + // success: false + // }); + next(err); + } }; // @desc Create new bootcamp // @route POST /api/v1/bootcamps // @access Private -exports.createBootcamp = (req, res, next) => { - res.status(200).json({success: true, msg: 'Create new bootcamp'}); +exports.createBootcamp = async (req, res, next) => { + try { + const bootcamp = await Bootcamp.create(req.body); + + res.status(201).json({ + success: true, + data: bootcamp + }); + } catch (err) { + res.status(400).json({success: false}); + } }; // @desc Update single bootcamp // @route PUT /api/v1/bootcamps/:id // @access Private -exports.updateBootcamp = (req, res, next) => { - res.status(200).json({success: true, msg: `Update bootcamp ${req.params.id}`}); +exports.updateBootcamp = async (req, res, next) => { + try { + const bootcamp = await Bootcamp.findByIdAndUpdate( + req.params.id, + req.body, + { + new: true, // response become supdates data + runValidators: true + } + ); + + if (!bootcamp) return res.status(400).json({success: false}); + + res.status(200).json({success: true, data: bootcamp}); + } catch (err) { + res.status(400).json({success: false}); + } + }; // @desc Delete Single Bootcamp // @route DELETE /api/v1/bootcamps/:id // @access Provate -exports.deleteBootcamp = (req, res, next) => { - res.status(200).json({success: true, msg: `Delete bootcamp ${req.params.id}`}); +exports.deleteBootcamp = async (req, res, next) => { + try { + const bootcamp = await Bootcamp.findByIdAndDelete(req.params.id); + + if (!bootcamp) return res.status(400).json({success: false}); + + res.status(200).json({success: true, data: {}}); + + } catch (err) { + res.status(400).json({success: false}); + } }; \ No newline at end of file diff --git a/middleware/error.js b/middleware/error.js new file mode 100644 index 0000000..a36b021 --- /dev/null +++ b/middleware/error.js @@ -0,0 +1,11 @@ +const errorHandler = (err, req, res, next) => { + // Log to console for dev + console.log(err.stack.red); + + res.status(500).json({ + success: false, + error: err.message + }); +} + +module.exports = errorHandler; \ No newline at end of file diff --git a/models/Bootcamp.js b/models/Bootcamp.js new file mode 100644 index 0000000..f80991d --- /dev/null +++ b/models/Bootcamp.js @@ -0,0 +1,102 @@ +const mongoose = require('mongoose'); + +const BootcampSchema = new mongoose.Schema({ + name: { + type: String, + required: [true, 'Please add a name'], + unique: true, + trim: true, + maxLength: [50, "Name cannot be more than 50 characters"] + }, + slug: String, + description: { + type: String, + required: [true, 'Please add a description'], + maxlength: [500, 'Description can not be more than 500 characters'] + }, + website: { + type: String, + match: [ + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, + 'Please use a valid URL with HTTP or HTTPS' + ] + }, + phone: { + type: String, + maxlength: [20, 'Phone number can not be longer than 20 characters'] + }, + email: { + type: String, + match: [ + /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, + 'Please add a valid email' + ] + }, + address: { + type: String, + required: [true, 'Please add an address'] + }, + location: { + // GeoJSON Point + type: { + type: String, + enum: ['Point'] + }, + coordinates: { + type: [Number], + index: '2dsphere' + }, + formattedAddress: String, + street: String, + city: String, + state: String, + zipcode: String, + country: String + }, + careers: { + // Array of strings + type: [String], + required: true, + // only avaliable values that it can have + enum: [ + 'Web Development', + 'Mobile Development', + 'UI/UX', + 'Data Science', + 'Business', + 'Other' + ] + }, + averageRating: { + type: Number, + min: [1, 'Rating must be at least 1'], + max: [10, 'Rating must can not be more than 10'] + }, + averageCost: Number, + photo: { + type: String, + default: 'no-photo.jpg' + }, + housing: { + type: Boolean, + default: false + }, + jobAssistance: { + type: Boolean, + default: false + }, + jobGuarantee: { + type: Boolean, + default: false + }, + acceptGi: { + type: Boolean, + default: false + }, + createdAt: { + type: Date, + default: Date.now + } +}); + +module.exports = mongoose.model('Bootcamp', BootcampSchema); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 08a164c..24550d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "colors": "^1.4.0", "dotenv": "^8.2.0", "express": "^4.17.1", "mongoose": "^5.11.14", @@ -452,6 +453,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2434,6 +2443,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", diff --git a/package.json b/package.json index bb1d676..7c68708 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "homepage": "https://github.com/garance-buricatu/Udemy_Node#readme", "dependencies": { + "colors": "^1.4.0", "dotenv": "^8.2.0", "express": "^4.17.1", "mongoose": "^5.11.14", diff --git a/server.js b/server.js index 9819ca2..fbd218d 100644 --- a/server.js +++ b/server.js @@ -2,6 +2,10 @@ const express = require('express'); const dotenv = require('dotenv'); const morgan = require('morgan'); const connectDB = require('./config/db'); +const colors = require('colors'); + +// Middlwares +const errorHandler = require('./middleware/error'); /** *-------------------- EXPRESS APIs ---(see routes/bootcamps file)------------ @@ -49,6 +53,9 @@ const bootcamps = require('./routes/bootcamps'); const app = express(); +// Body Parser --> allows APIs to use "req.body" variable +app.use(express.json()); + //** Morgan dev logging middleware */ if (process.env.NODE_ENV === 'development'){ app.use(morgan('dev')); @@ -57,14 +64,16 @@ if (process.env.NODE_ENV === 'development'){ // Mount routers (from bootcamps file) app.use('/api/v1/bootcamps', bootcamps); +app.use(errorHandler); + const PORT = process.env.PORT || 7000; // run server -const server = app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`)); +const server = app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold)); // Handle unhandled promise rejections (ie. async await promises) process.on('unhandledRejection', (err, promise) => { - console.log(`Error: ${err.message}`); + console.log(`Error: ${err.message}`.red); // Close server and exit process server.close(() => process.exit(1));