diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..e9a2fac --- /dev/null +++ b/app.js @@ -0,0 +1,22 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const app = express(); +// const models = require('./models'); + +app.use(bodyParser.json()); +app.set('view engine', 'ejs'); +app.use(bodyParser.urlencoded({ + extended: false +})); + +const menu = require('./routes/menu') +const restaurant = require('./routes/restaurant') + +app.get('/', (req, res) => { + res.send('Hello Word') +}); + +app.use('/menus', menu); +app.use('/restaurants', restaurant); + +app.listen(3000, () => console.log(`The App listening on port 3000!`)); \ No newline at end of file diff --git a/config/config.json b/config/config.json new file mode 100644 index 0000000..a92e0ef --- /dev/null +++ b/config/config.json @@ -0,0 +1,9 @@ +{ + "development": { + "username": "postgres", + "password": "postgres", + "database": "platinum_livecode4", + "host": "127.0.0.1", + "dialect": "postgres" + } +} diff --git a/helper/format_currency.js b/helper/format_currency.js new file mode 100644 index 0000000..4fb19dc --- /dev/null +++ b/helper/format_currency.js @@ -0,0 +1,5 @@ +function format_currency(num) { + return num.toLocaleString() +} + +module.exports = format_currency \ No newline at end of file diff --git a/migrations/20180301021557-create-restaurant.js b/migrations/20180301021557-create-restaurant.js new file mode 100644 index 0000000..62007ca --- /dev/null +++ b/migrations/20180301021557-create-restaurant.js @@ -0,0 +1,30 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Restaurants', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + name: { + type: Sequelize.STRING + }, + address: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Restaurants'); + } +}; \ No newline at end of file diff --git a/migrations/20180301021744-create-menu.js b/migrations/20180301021744-create-menu.js new file mode 100644 index 0000000..1214453 --- /dev/null +++ b/migrations/20180301021744-create-menu.js @@ -0,0 +1,36 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Menus', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + name: { + type: Sequelize.STRING + }, + menu_type: { + type: Sequelize.STRING + }, + rating: { + type: Sequelize.INTEGER + }, + price: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Menus'); + } +}; \ No newline at end of file diff --git a/migrations/20180301024403-addcolumn_reataurant.js b/migrations/20180301024403-addcolumn_reataurant.js new file mode 100644 index 0000000..756ec0a --- /dev/null +++ b/migrations/20180301024403-addcolumn_reataurant.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + */ + return queryInterface.addColumn('Menus', 'id_restaurant', { type: Sequelize.INTEGER }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + } +}; diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..5662f10 --- /dev/null +++ b/models/index.js @@ -0,0 +1,36 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var Sequelize = require('sequelize'); +var basename = path.basename(__filename); +var env = process.env.NODE_ENV || 'development'; +var config = require(__dirname + '/../config/config.json')[env]; +var db = {}; + +if (config.use_env_variable) { + var sequelize = new Sequelize(process.env[config.use_env_variable], config); +} else { + var sequelize = new Sequelize(config.database, config.username, config.password, config); +} + +fs + .readdirSync(__dirname) + .filter(file => { + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); + }) + .forEach(file => { + var model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(modelName => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/models/menu.js b/models/menu.js new file mode 100644 index 0000000..b0d0902 --- /dev/null +++ b/models/menu.js @@ -0,0 +1,79 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + const Op = sequelize.Op + var Menu = sequelize.define('Menu', { + name: DataTypes.STRING, + menu_type: { + type: DataTypes.STRING, + validate: { + isIn: { + args: ['food', 'drink'], + msg: "isi menu type dengan food / drink!" + }, + // isUpdate: (value, option) => { + // console.log('-----------', value) + // Menu.findOne({ + // where: { + // menu_type: { + // [Op.ne]: value, + // } + // } + // }) + // .then(data => { + // console.log('sini'); + // console.log(data.id,'-----=+++++++++'); + // if (data.menu_type === value) { + // next() + // } else { + // next('isi menu type dengan food / drink!') + // } + + // }) + // .catch(err => { + // console.log('sana') + // }) + // } + } + }, + rating: DataTypes.INTEGER, + price: DataTypes.STRING, + id_restaurant: { + type: DataTypes.INTEGER, + validate: { + checkRes: (value, next) => { + Menu.findAll({ + where: { + id_restaurant: value + } + }) + .then(data => { + if (data.length > 4) { + console.log(data.length, '----------------------') + next(`Varian Food sudah maksimal !`) + } else { + next() + } + }) + .catch(err => { + console.log(err) + }) + } + } + } + }, { + hooks: { + beforeCreate: (value, option) => { + if (value.menu_type == 'food' && value.price == 0) { + value.price = 15000 + } + if (value.menu_type == 'drink' && value.price == 0) { + value.price = 10000 + } + } + } + }); + Menu.associate = function(models) { + Menu.belongsTo(models.Restaurant, { foreignKey: 'id_restaurant'} ) + }; + return Menu; +}; \ No newline at end of file diff --git a/models/restaurant.js b/models/restaurant.js new file mode 100644 index 0000000..1aaa379 --- /dev/null +++ b/models/restaurant.js @@ -0,0 +1,12 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + var Restaurant = sequelize.define('Restaurant', { + name: DataTypes.STRING, + address: DataTypes.TEXT + }, {}); + Restaurant.associate = function(models) { + Restaurant.hasMany(models.Menu, { foreignKey: 'id_restaurant' }) + + }; + return Restaurant; +}; \ No newline at end of file diff --git a/routes/menu.js b/routes/menu.js new file mode 100644 index 0000000..b8333fa --- /dev/null +++ b/routes/menu.js @@ -0,0 +1,102 @@ +const router = require('express').Router() +const { Menu, Restaurant } = require('../models'); + +router.get('/', (req,res) => { + Menu.findAll({ + include: Restaurant + }) + .then(data => { + Restaurant.findAll() + .then(dataRes => { + // console.log(data) + let err = null + res.render('menu', { data, dataRes, err, helper: require('../helper/format_currency') }) + }) + .catch(err => { + console.log(err) + }) + }) + .catch(err => { + console.log(err) + }) +}); + +router.post('/', (req,res) => { + let dataAddObj = { + name: req.body.name, + menu_type: req.body.menu_type, + rating: req.body.rating, + price: req.body.price, + id_restaurant: req.body.id_restaurant + } + Menu.create(dataAddObj) + .then(success => { + res.redirect('/menus') + }) + .catch(err => { + Menu.findAll({ + include: Restaurant + }) + .then(data => { + Restaurant.findAll() + .then(dataRes => { + res.render('menu', { data, dataRes, err, helper: require('../helper/format_currency') }) + console.log(err) + }) + }) + }) +}); + +router.get('/:id/edit', (req,res) => { + Menu.findById(req.params.id) + .then(data => { + Restaurant.findAll() + .then(dataRes => { + console.log(data) + res.render('edit_menu', { data, dataRes }) + }) + .catch(err => { + console.log(err) + }) + }) + .catch(err => { + console.log(err) + }) +}); + +router.post('/:id/edit', (req, res) => { + let dataEditObj = { + name: req.body.name, + menu_type: req.body.menu_type, + rating: req.body.rating, + price: req.body.price, + id_restaurant: req.body.id_restaurant + } + Menu.update(dataEditObj, { + where : { + id: req.params.id + } + }) + .then(data => { + res.redirect('/menus') + }) + .catch(err => { + console.log(err) + }) +}); + +router.get('/:id/delete', (req,res) => { + Menu.destroy({ + where: { + id: req.params.id + } + }) + .then(data => { + res.redirect('/menus') + }) + .catch(err => { + console.log(err) + }) +}) + +module.exports = router \ No newline at end of file diff --git a/routes/restaurant.js b/routes/restaurant.js new file mode 100644 index 0000000..2e2a0f8 --- /dev/null +++ b/routes/restaurant.js @@ -0,0 +1,65 @@ +const router = require('express').Router() +const { Menu, Restaurant } = require('../models'); + +router.get('/', (req, res) => { + Restaurant.findAll() + .then(dataRes => { + let err = null + res.render('restaurant', { dataRes}) + }) + .catch(err => { + console.log(err) + }) + .catch(err => { + console.log(err) + }) +}); + +router.get('/:id/view_menu', (req,res) => { + Menu.findAll({ + where: { + id_restaurant: req.params.id + } + }) + .then(data => { + Restaurant.findById(req.params.id) + .then(dataRes => { + console.log(data) + res.render('view_menu', { data, dataRes, helper: require('../helper/format_currency') }) + }) + .catch(err => { + console.log(err) + }) + }) +}) + +router.post('/:id/search', (req,res) => { + console.log(req.params.id); + console.log(req.body.type_search); + console.log(req.body.input); + var query = null + if (req.body.type_search === 'name') { + query = 'name'; + } else if (req.body.type_search === 'menu_type') { + query = 'menu_type' + } else if (req.body.type_search === 'rating') { + query = 'rating' + } else { + query = 'price' + } + + // Menu.findAll({ + // where: { + // query: req.body.input + // } + // }) + // .then(dataSearch => { + // console.log(dataSearch) + // }) + // .catch(err => { + // console.log(err) + // }) +}) + + +module.exports = router \ No newline at end of file diff --git a/seeders/20180301021931-insert_restaurant.js b/seeders/20180301021931-insert_restaurant.js new file mode 100644 index 0000000..8db676a --- /dev/null +++ b/seeders/20180301021931-insert_restaurant.js @@ -0,0 +1,46 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkInsert('Person', [{ + name: 'John Doe', + isBetaMember: false + }], {}); + */ + return queryInterface.bulkInsert('Restaurants', [ + { + name: 'KFC', + address: 'Jakarta Timur', + createdAt: new Date(), + updatedAt: new Date() + }, + { + name: 'Pizza Hut', + address: 'Jakarta Pusat', + createdAt: new Date(), + updatedAt: new Date() + }, + { + name: 'Dons Burger', + address: 'Jakarta Barat', + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkDelete('Person', null, {}); + */ + } +}; diff --git a/views/edit_menu.ejs b/views/edit_menu.ejs new file mode 100644 index 0000000..eb9fd57 --- /dev/null +++ b/views/edit_menu.ejs @@ -0,0 +1,32 @@ + + + + + + Page Title + + + + + +

+
+ +

+ +

+ +

+ +

+ +

+ +
+ + + \ No newline at end of file diff --git a/views/menu.ejs b/views/menu.ejs new file mode 100644 index 0000000..4ea61ef --- /dev/null +++ b/views/menu.ejs @@ -0,0 +1,68 @@ + + + + + + View Menu + + + + + +

Menu

+ + + + + + + + + + + + + + <%data.map(val => {%> + + + + + + + + + + <%})%> + + +
IdNameMenu TypeRatingPriceRestaurant_IdAction
<%= val.id %><%= val.name %><%= val.menu_type %><%= val.rating %><%= helper(Number(val.price)) %><%= val.Restaurant.name %> + Edit + Delete +
+ +
+
+ <% if (err) { %> + <%= err %> + <% } %> +

+
+ +

+ +

+ +

+ +

+ +

+ +
+ + \ No newline at end of file diff --git a/views/restaurant.ejs b/views/restaurant.ejs new file mode 100644 index 0000000..4bd7d48 --- /dev/null +++ b/views/restaurant.ejs @@ -0,0 +1,39 @@ + + + + + + Page Title + + + + + + +

Restaurant

+ + + + + + + + + + + <%dataRes.map(val => {%> + + + + + + + <%})%> + + +
IdNameAddressAction
<%= val.id %><%= val.name %><%= val.address %> + View Menu +
+ + + \ No newline at end of file diff --git a/views/view_menu.ejs b/views/view_menu.ejs new file mode 100644 index 0000000..ac0c162 --- /dev/null +++ b/views/view_menu.ejs @@ -0,0 +1,55 @@ + + + + + + Page Title + + + + + + +

+ Menu Restaurant: <%= dataRes.name %> +

+ +
+ Search + + Keyword: + +
+
+
+ + + + + + + + + + + + <%data.map(val => {%> + + + + + + + + <%})%> + + +
IdNameMenu TypeRatingPrice
<%= val.id %><%= val.name %><%= val.menu_type %><%= val.rating %><%= helper(Number(val.price)) %>
+ + + \ No newline at end of file