diff --git a/backend/app.js b/backend/app.js index ae8a5b2..d839375 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1,28 +1,44 @@ +//zaladowanie modolow dodatkowych i plikow aplikacji var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var logger = require('morgan'); - var indexRouter = require('./routes/index'); -var usersRouter = require('./routes/users'); +//var usersRouter = require('./routes/users'); +var cors = require('cors'); + +const errors = require('./middlewares/errors') + + + +//db +require('./db/mongoose') + var app = express(); +app.options('*', cors()) +app.use(cors()); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); app.use(logger('dev')); -app.use(express.json()); -app.use(express.urlencoded({ extended: true })); //was false +// app.use(express.json()); +// app.use(express.urlencoded({ extended: true })); //was false +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended:true})); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); -app.use('/users', usersRouter); +// errors handling +// app.use(errors.notFound()); +// app.use(errors.catchErrors()); +//app.use('/users', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { @@ -40,4 +56,6 @@ app.use(function(err, req, res, next) { res.render('error'); }); + + module.exports = app; diff --git a/backend/controllers/CategoriesController.js b/backend/controllers/CategoriesController.js new file mode 100644 index 0000000..26df5d7 --- /dev/null +++ b/backend/controllers/CategoriesController.js @@ -0,0 +1,11 @@ +const Category = require('../db/models/category') + + + +async function findAll(req, res) { + const categories = await Category.find().sort({ createdAt: 'desc' }); + return res.status(200).send({ data: categories }); +} + + +module.exports.findAll = findAll diff --git a/backend/controllers/IndexController.js b/backend/controllers/IndexController.js new file mode 100644 index 0000000..2df9ba7 --- /dev/null +++ b/backend/controllers/IndexController.js @@ -0,0 +1,3 @@ +exports.home = (req, res) => { + res.json({'status':'working very well!'}); + } \ No newline at end of file diff --git a/backend/controllers/OrderStatusesController.js b/backend/controllers/OrderStatusesController.js new file mode 100644 index 0000000..6d6ef39 --- /dev/null +++ b/backend/controllers/OrderStatusesController.js @@ -0,0 +1,11 @@ +const OrderStatus = require('../db/models/order-status') + + + +async function findAll(req, res) { + const orderStatutes = await OrderStatus.find().sort({ createdAt: 'desc' }); + return res.status(200).send({ data: orderStatutes }); +} + + +module.exports.findAll = findAll \ No newline at end of file diff --git a/backend/controllers/OrdersController.js b/backend/controllers/OrdersController.js new file mode 100644 index 0000000..d11eef9 --- /dev/null +++ b/backend/controllers/OrdersController.js @@ -0,0 +1,119 @@ +const Order = require('../db/models/order'); +const OrderStatus = require('../db/models/order-status') + + + +async function findOne(req, res, next) { + const orderStatus = await OrderStatus.findOne({slug : req.params.slug}) + if (!orderStatus) return res.status(404).send({message: `Order was not found` }); + + const ref = orderStatus._id + + const orders = await Order.find({ orderStatus: ref }).populate({ + path: 'products orderStatus', + populate: { path: 'product_id'} + }); + + if (!orders) return res.status(404).send({message: `Order was not found` }); + + + return res.status(200).send({ data: orders }); +} + +async function findAll(req, res) { + const orders = await Order.find().sort({ createdAt: 'desc' }) + .populate({ + path: 'products orderStatus', + populate: { path: 'product_id'} + }); + return res.status(200).send({ data: orders }); +} + +async function create(req, res) { + try { + console.log(req.body.products) + const order = await new Order({ + date: req.body.date, + orderStatus: req.body.orderStatusID, + userName: req.body.userName, + email: req.body.email, + phone: req.body.phone, + products: req.body.products, + + }).save() + + return res.status(201).send({ data: order, message: `Order was created` }); + } catch (err) { + return res.status(400).send({message: `Order was not created`, error: err }); + + } +} + +async function update(req, res, next) { + try { + + const orderStatus = await OrderStatus.findOne({slug : req.body.orderStatusID}) + if (!orderStatus) return res.status(400).send({message: `Order was not updated21`}); + + const reference = orderStatus._id + + let order = await Order.findOne({ _id: req.params.id}); + if (!order) return res.status(404).send({message: `Order was not updated` }); + + + const canceled = await OrderStatus.findOne({slug : "canceled"}) + const notApproved = await OrderStatus.findOne({slug : "not-approved"}) + const approved = await OrderStatus.findOne({slug : "approved"}) + const completed = await OrderStatus.findOne({slug : "completed"}) + + + if (order.orderStatus._id.equals(canceled._id)) + return res.status(400).send({message: `Order was not updated`}); + + if (order.orderStatus._id.equals(approved._id) && (reference.equals(notApproved._id) || reference.equals(canceled._id))) + return res.status(400).send({message: `Order was not updated`}); + + if (order.orderStatus._id.equals(completed._id) && (reference.equals(notApproved._id) || reference.equals(approved._id) || reference.equals(canceled._id))) + return res.status(400).send({message: `Order was not updateded`}); + + const updatedOrder = await Order.updateOne( + { + _id: req.params.id + }, + {$set: + { + //TODO walidacja dla nieustawiania zlego statusu + orderStatus: reference, + + + }}) + + + } catch (err) { + return res.status(400).send({message: `Order was not updated`, error: err }); + } + + + + + order = await Order.findOne({ _id: req.params.id }).populate({ + path: 'products orderStatus', + populate: { path: 'product_id'} + });; + return res.status(200).send({ data: order, message: `Order was updated` }); +} + +async function remove(req, res, next) { + const order = await Order.findOne({ _id: req.params.id }); + if (!order) return next(); + await order.remove(); + + return res.status(200).send({ message: `Order was removed` }); +} + + +module.exports.findOne = findOne +module.exports.findAll = findAll +module.exports.create = create +module.exports.update = update +module.exports.remove = remove \ No newline at end of file diff --git a/backend/controllers/ProductsController.js b/backend/controllers/ProductsController.js new file mode 100644 index 0000000..16940ca --- /dev/null +++ b/backend/controllers/ProductsController.js @@ -0,0 +1,70 @@ +const Product = require('../db/models/product'); + +async function findOne(req, res, next) { + const product = await Product.findOne({ slug: req.params.slug }).populate('category','-slug -createdAt -updatedAt -__v'); + if (!product) return next(); + return res.status(200).send({ data: product }); +} + +async function findAll(req, res) { + const products = await Product.find().sort({ createdAt: 'desc' }) + .populate('category','-slug -createdAt -updatedAt -__v'); + return res.status(200).send({ data: products }); +} + +async function create(req, res) { + try { + const product = await new Product({ + name: req.body.name, + description: req.body.description, + price: req.body.price, + weight: req.body.weight, + category: req.body.category, + }).save(); + + return res.status(201).send({ data: product, message: `Product was created` }); + + } catch (err) { + return res.status(400).send({message: `Product was not created, bad request`, error: err}); + } +} + +async function update(req, res, next) { + let product = await Product.findOne({ slug: req.params.slug }); + if (!product) return res.status(404).send({message: `Product was not updated, bad request`}); + + const query = { + slug: req.params.slug + } + const update = {$set: { + name: req.body.name, + description: req.body.description, + price: req.body.price, + weight: req.body.weight, + category: req.body.categoryID + }} + const options = {runValidators: true} + + try { + const updatedProduct = await Product.updateOne(query, update, options) + product = await Product.findOne({ slug: req.params.slug }); + return res.status(200).send({ data: product, message: `Product was updated` }); + } catch (err) { + return res.status(400).send({message: `Product was not created, bad request`, error: err}); + } +} + +async function remove(req, res, next) { + const product = await Product.findOne({ slug: req.params.slug }); + if (!product) return next(); + await product.remove(); + + return res.status(200).send({ message: `Product was removed` }); +} + + +module.exports.findOne = findOne +module.exports.findAll = findAll +module.exports.create = create +module.exports.update = update +module.exports.remove = remove \ No newline at end of file diff --git a/backend/data/db.js b/backend/data/db.js deleted file mode 100644 index d82fef4..0000000 --- a/backend/data/db.js +++ /dev/null @@ -1,23 +0,0 @@ -const mongoClient = require('mongodb').MongoClient; - -const url = 'mongodb://127.0.0.1:27017' -const dbname = 'mongo-shop' - -mongoClient.connect(url, {}, (error, client) => { - if (error) - console.log('Cannot connect to the database') - const db = client.db(dbname) - - //users - db.collection('users').insertOne({ - name: 'Jon', - age: 20 - - }, (error, result) => { - if (error) - console.log('Adding user error', error) - console.log(result.ops) - }) - - console.log('Database connected') -}) \ No newline at end of file diff --git a/backend/db/models/category.js b/backend/db/models/category.js new file mode 100644 index 0000000..1a6292e --- /dev/null +++ b/backend/db/models/category.js @@ -0,0 +1,24 @@ +const mongoose = require('mongoose') +const URLSlugs = require('mongoose-url-slugs'); + +const predifinedNames = ['phone', 'pc', 'laptop', 'gps'] + +const categorySchema = new mongoose.Schema({ + name: { + type: String, + lowercase: true, + required: true, + unique: true, + validate(value) { + if (!predifinedNames.includes(this.name)) {throw new Error('Use predifiend names!')} + } + }, +}, { + timestamps: true +}); + +categorySchema.plugin(URLSlugs('name', { field: 'slug', update: true })); + +const Category = mongoose.model('Category', categorySchema); + +module.exports = Category diff --git a/backend/db/models/order-status.js b/backend/db/models/order-status.js new file mode 100644 index 0000000..cef7bfc --- /dev/null +++ b/backend/db/models/order-status.js @@ -0,0 +1,24 @@ +const mongoose = require('mongoose') +const URLSlugs = require('mongoose-url-slugs'); + +const predifinedNames = ['not approved', 'approved', 'canceled', 'completed'] + +const ordersStatusSchema = new mongoose.Schema({ + name: { + type: String, + lowercase: true, + required: true, + unique: true, + validate(value) { + if (!predifinedNames.includes(this.name)) {throw new Error('Use predifiend names!')} + } + }, +}, { + timestamps: true +}); + +ordersStatusSchema.plugin(URLSlugs('name', { field: 'slug', update: true })); + +const OrderStatus = mongoose.model('OrderStatus', ordersStatusSchema); + +module.exports = OrderStatus \ No newline at end of file diff --git a/backend/db/models/order.js b/backend/db/models/order.js new file mode 100644 index 0000000..cea84b4 --- /dev/null +++ b/backend/db/models/order.js @@ -0,0 +1,58 @@ +const { Decimal128 } = require('mongodb'); +const mongoose = require('mongoose') +const URLSlugs = require('mongoose-url-slugs'); +const OrderStatus = require('./order-status') +const Product = require('./product') + +const orderSchema = new mongoose.Schema({ + date: { + type: Date, + required: false, + + }, + orderStatus: { + type: mongoose.Schema.Types.ObjectId, + ref: OrderStatus, + required: true, + + }, + userName: { + type: String, + required: true, + + }, + email: { + type: String, + required: true, + }, + phone: { + type: String, + required: true, + validate(val) { + const phoneForm = /^\d{9}$/; + if (!this.phone.match(phoneForm)) {throw new Error('Wrong number type!')} + }, + + }, + products: { + product_id : { + type: [mongoose.Schema.Types.ObjectId], + required: true, + ref: Product, + + }, + count: { + type: Number, + default: 1, + min: 1 + }, + } + }, { + timestamps: true +}); + +//orderSchema.plugin(URLSlugs('name', { field: 'slug', update: true })); + +const Order = mongoose.model('Order', orderSchema); + +module.exports = Order \ No newline at end of file diff --git a/backend/db/models/product.js b/backend/db/models/product.js new file mode 100644 index 0000000..c6bf212 --- /dev/null +++ b/backend/db/models/product.js @@ -0,0 +1,48 @@ +const mongoose = require('mongoose') +const URLSlugs = require('mongoose-url-slugs'); +const Category = require('./category') + +const productSchema = new mongoose.Schema({ + name: { + type: String, + lowercase: true, + required: true, + + }, + description: { + type: String, + required: true, + + }, + price: { + type: Number, + min: 0.01, + required: true, + + }, + weight: { + type: Number, + min: 0.01, + required: true, + + }, + category: [{ + type: mongoose.Schema.Types.ObjectId, + ref: Category, + required: true, + + }] + }, { + timestamps: true +}); + +productSchema.plugin(URLSlugs('name', { field: 'slug', update: true })); +productSchema.pre('save', function(next) { + if (this.category.length == 0) { + throw new Error('At least one category') + } + next() +}) +const Product = mongoose.model('Product', productSchema); + +module.exports = Product \ No newline at end of file diff --git a/backend/db/mongoose.js b/backend/db/mongoose.js new file mode 100644 index 0000000..521a314 --- /dev/null +++ b/backend/db/mongoose.js @@ -0,0 +1,9 @@ +const mongoose = require('mongoose') + +const url = 'mongodb://127.0.0.1:27017/mongo-shop' + +mongoose.connect(url, { + useNewUrlParser: true, + useCreateIndex: true, + useUnifiedTopology: true +}) diff --git a/backend/db/test-db.js b/backend/db/test-db.js new file mode 100644 index 0000000..4ea7540 --- /dev/null +++ b/backend/db/test-db.js @@ -0,0 +1,142 @@ +//TODO rozlozyc ten plik na inne pliki + +require('./mongoose') +const Category = require('./models/category') +const Product = require('./models/product') +const OrderStatus = require('./models/order-status') +const Order = require('./models/order') + +const createUser = async (data) => { + try { + const user = new User(data) + await user.save() + console.log(user) + } catch (err) { + console.log(err) + } +} + +const findUsers = async () => { + try { + const users = await User.find({}) + console.log(users) + } catch (error) { + console.log(error) + } +} + + +const createCategory = async (data) => { + try { + const category = new Category(data) + await category.save() + console.log(category) + } catch (err) { + console.log(err) + } +} + +const findCategories = async () => { + try { + const category = await Category.find({}) + console.log(category) + } catch (error) { + console.log(error) + } +} + +const createProduct = async (data) => { + try { + const product = new Product(data) + await product.save() + console.log(product) + } catch (err) { + console.log(err) + } +} + +const findProducts = async () => { + try { + const product = await Product.find({}).populate('category','-slug -createdAt -updatedAt -__v'); + console.log(product) + } catch (error) { + console.log(error) + } +} + +const createOrder= async (data) => { + try { + const order = new Order(data) + await order.save() + console.log(order) + } catch (err) { + console.log(err) + } +} + +const findOrders = async () => { + try { + const orders = await Order.find({}).populate("products product_id"); + console.log(orders) + } catch (error) { + console.log(error) + } +} + + +const createOrderStatus= async (data) => { + try { + const orderStatus = new OrderStatus(data) + await orderStatus.save() + console.log(orderStatus) + } catch (err) { + console.log(err) + } +} + +const findOrderStatuses = async () => { + try { + const orderStatus = await OrderStatus.find({}); + console.log(orderStatus) + } catch (error) { + console.log(error) + } +} + + +//create +// createOrderStatus({name: 'not approved'}) +// createOrderStatus({name: 'approved'}) +// createOrderStatus({name: 'canceled'}) +// createOrderStatus({name: 'completed'}) + + +// createCategory({ name: 'laptop'}) +// createCategory({ name: 'phone'}) +// createCategory({ name: 'pc'}) + +// createProduct({ +// name: 'Lenovo Notebook v1', +// description: 'Super laptop', +// price: 2200, +// weight: 22.33, +// category: "5ff89fbca617ea48413b4ad8" + +// }) + +createOrder({ + date: '2010-12-09', + orderStatus: "5ff8a01cd46aeb48742770f0", + userName: 'oskar123', + email: '123@gmail.com', + phone: '671999887', + products: [{product_id: "5ff8a0ae39d85348dddf5972", count: 2}, {product_id: "5ff8a0ae39d85348dddf5972", count: 20}] +}) + + +//find methods + +// findCategories() +// findOrderStatuses() +// findProducts() +// findOrders() \ No newline at end of file diff --git a/backend/middlewares/errors.js b/backend/middlewares/errors.js new file mode 100644 index 0000000..7f7e886 --- /dev/null +++ b/backend/middlewares/errors.js @@ -0,0 +1,17 @@ +exports.notFound = (req, res, next) => { + const err = new Error('404 page not found'); + err.status = 404; + next(err); +} + +exports.catchAsync = (fn) => { + return (req, res, next) => { + fn(req, res, next).catch(err => next(err)); + } +} +exports.catchErrors = (err, req, res, next) => { + res.status(err.status || 500); + res.render('error', { + message: err.message + }); +} diff --git a/backend/package-lock.json b/backend/package-lock.json index 630e555..6c88de8 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -17,6 +17,28 @@ "@types/babel-types": "*" } }, + "@types/bson": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", + "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mongodb": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.3.tgz", + "integrity": "sha512-6YNqGP1hk5bjUFaim+QoFFuI61WjHiHE1BNeB41TA00Xd2K7zG4lcWyLLq/XtIp36uMavvS5hoAUJ+1u/GcX2Q==", + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -120,6 +142,11 @@ "safe-buffer": "^5.1.1" } }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -260,6 +287,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -423,6 +459,11 @@ } } }, + "extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=" + }, "finalhandler": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", @@ -574,6 +615,11 @@ "promise": "^7.0.1" } }, + "kareem": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", + "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -649,6 +695,45 @@ "saslprep": "^1.0.0" } }, + "mongoose": { + "version": "5.11.10", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.10.tgz", + "integrity": "sha512-daE2L6VW7WNywv7tL2KUkBViWvODbzr50Of1kJpIbzW3w3N5/TYcgSmhCsEDWfYGQXbun2rdd7+sOdsEC8zQSQ==", + "requires": { + "@types/mongodb": "^3.5.27", + "bson": "^1.1.4", + "kareem": "2.3.2", + "mongodb": "3.6.3", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.8.3", + "mquery": "3.2.3", + "ms": "2.1.2", + "regexp-clone": "1.0.0", + "safe-buffer": "5.2.1", + "sift": "7.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mongoose-url-slugs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-url-slugs/-/mongoose-url-slugs-1.0.2.tgz", + "integrity": "sha512-Hel+Xj0numcz9NMrt/TL8NRhpfyfkN1W97UcncZ0NcB5Pcg/870/fQnqVs7RPtC+BST/zHEmM1U0rQBx3Ea5mQ==", + "requires": { + "extend": "3.0.0" + } + }, "morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", @@ -661,6 +746,38 @@ "on-headers": "~1.0.1" } }, + "mpath": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz", + "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==" + }, + "mquery": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.3.tgz", + "integrity": "sha512-cIfbP4TyMYX+SkaQ2MntD+F2XbqaBHUYWk3j+kqdDztPWok3tgyssOZxMHMtzbV1w9DaSlvEea0Iocuro41A4g==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "^1.0.0", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -901,6 +1018,11 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, + "regexp-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", + "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" + }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -1004,6 +1126,16 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "sift": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", + "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", @@ -1088,6 +1220,11 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "optional": true }, + "underscore": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz", + "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index f96edb7..7f58f13 100644 --- a/backend/package.json +++ b/backend/package.json @@ -2,17 +2,22 @@ "name": "myshop-app", "version": "1.0.0", "private": true, + "main": "app.js", "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "^1.19.0", "cookie-parser": "~1.4.4", + "cors": "^2.8.5", "debug": "~2.6.9", "express": "^4.16.4", "http-errors": "^1.6.3", "mongodb": "^3.6.3", + "mongoose": "^5.11.10", + "mongoose-url-slugs": "^1.0.2", "morgan": "^1.9.1", - "pug": "^2.0.0-beta11" + "pug": "^2.0.0-beta11", + "underscore": "^1.12.0" } } diff --git a/backend/routes/index.js b/backend/routes/index.js index ecca96a..0d55f4e 100644 --- a/backend/routes/index.js +++ b/backend/routes/index.js @@ -1,9 +1,37 @@ var express = require('express'); var router = express.Router(); +const errors = require('../middlewares/errors') +const IndexController = require('../controllers/IndexController'); +const ProductsContorller = require('../controllers/ProductsController'); +const CategoryController = require('../controllers/CategoriesController') +const OrdersController = require('../controllers/OrdersController') +const OrderStatutesController = require('../controllers/OrderStatusesController') /* GET home page. */ -router.get('/', function(req, res, next) { - res.render('index', { title: 'Express' }); -}); +router.get('/', IndexController.home); + + +/* GET /categories */ +router.get('/categories', errors.catchAsync(CategoryController.findAll)); + +/* GET /products */ +router.get('/products', errors.catchAsync(ProductsContorller.findAll)); +router.get('/products/:slug', errors.catchAsync(ProductsContorller.findOne)); +router.post('/products', errors.catchAsync(ProductsContorller.create)); +//TODO fix put method +router.put('/products/:slug', errors.catchAsync(ProductsContorller.update)); + +/* GET /orders */ +router.get('/orders', errors.catchAsync(OrdersController.findAll)); +//TODO fix put and post method +router.post('/orders', errors.catchAsync(OrdersController.create)); +router.put('/orders/:id', errors.catchAsync(OrdersController.update)); +//TODO add another method to get method +router.get('/orders/status/:slug', errors.catchAsync(OrdersController.findOne)); + + +/* GET /categories */ +router.get('/status', errors.catchAsync(OrderStatutesController.findAll)); + module.exports = router; diff --git a/backend/routes/users.js b/backend/routes/users.js deleted file mode 100644 index 623e430..0000000 --- a/backend/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/backend/server.js b/backend/server.js index 0e98812..f7357ad 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,15 +1,8 @@ -// const http = require('http'); -const express = require('express') -// const hostname = '127.0.0.1'; -// const port = 3000; +const app = require('./app'); -const app = express(); +app.set('port', 3000); -// respond with "hello world" when a GET request is made to the homepage -app.get('/', function (req, res) { - res.send('hello world') - }) - -app.listen(3000, function() { - console.log(`Server running!`); +const server = app.listen(app.get('port'), () => { + console.log(`Product service is listening on + ${server.address().port}`); }); \ No newline at end of file