diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..621038f --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..5e14503 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Curso POO con JavaScript + +## Pizza Place + +Aplicación simple para demostrar conceptos de Programación Orientada a Objetos con JavaScript + +Incluye diferentes *branches* para cada uno de los capítulos. + +Requiere [Node JS](https://nodejs.org) instalado + +**Uso** +- `git clone` o descargar como `.zip` +- `npm install` +- `npm run dev` +- Abrir navegador en `localhost:8080` diff --git a/index.html b/index.html index c13f653..10a9a77 100644 --- a/index.html +++ b/index.html @@ -1,11 +1,64 @@ - - Pizza Place - + + Pizza place + + - -

Pizza Place

+ +
+

Pizza Place

+
+
+
+
+
+
+ + +
+
+ +
+ +
+
+ +
+
+ +
+
+
+ + +
+ +
+
+
+
+
+

Pending Orders:

+
+
+
+
+
diff --git a/main.js b/main.js deleted file mode 100644 index 4c63ab5..0000000 --- a/main.js +++ /dev/null @@ -1 +0,0 @@ -console.log('Pizza place'); diff --git a/package.json b/package.json new file mode 100644 index 0000000..8c62773 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "pizzaplace", + "version": "1.0.0", + "description": "JavaScript POO", + "main": "webpack.config.js", + "devDependencies": { + "babel-core": "^6.24.1", + "babel-loader": "^6.4.1", + "babel-preset-es2015-native-modules": "^6.9.4", + "webpack": "^2.3.3", + "webpack-dev-server": "2" + }, + "scripts": { + "dev": "webpack-dev-server", + "build": "webpack --progress --watch" + }, + "author": "enrique7mc", + "license": "ISC" +} diff --git a/scripts-es6/datastore.js b/scripts-es6/datastore.js new file mode 100644 index 0000000..205dcce --- /dev/null +++ b/scripts-es6/datastore.js @@ -0,0 +1,23 @@ +class DataStore { + constructor() { + this.data = {}; + } + + add(key, val) { + this.data[key] = val; + } + + get(key) { + return this.data[key]; + } + + getAll() { + return this.data; + } + + remove(key) { + delete this.data[key]; + } +} + +export default DataStore; diff --git a/scripts-es6/main.js b/scripts-es6/main.js new file mode 100644 index 0000000..7dd2729 --- /dev/null +++ b/scripts-es6/main.js @@ -0,0 +1,32 @@ +import DataStore from './datastore'; +import Store from './store'; +import { PizzaOrder } from './order'; + +const store = new Store('ncc-1701', new DataStore()); +const form = document.querySelector('#pizza-form'); +form.addEventListener('submit', onSubmit); +const checklist = document.querySelector('#checklist'); + +// Event Handlers +function onSubmit(e) { + e.preventDefault(); + const email = form.querySelector('#emailInput').value; + const size = form.querySelector('input[name="size"]:checked').value; + const select = form.querySelector('#speciality'); + const speciality = select.options[select.selectedIndex].value; + const newOrder = new PizzaOrder({ + email, + size, + speciality + }); + store.createOrder(newOrder); + addToPending(newOrder); +} + +// Funciones +function addToPending(order) { + const orderDiv = document.createElement('div'); + const newContent = document.createTextNode(order.toString()); + orderDiv.appendChild(newContent); + checklist.appendChild(orderDiv); +} diff --git a/scripts-es6/order.js b/scripts-es6/order.js new file mode 100644 index 0000000..d287829 --- /dev/null +++ b/scripts-es6/order.js @@ -0,0 +1,49 @@ +/* // Herencia con clases +class BaseOrder { + constructor(email) { + this.email = email; + } +} + +class PizzaOrder extends BaseOrder { + constructor(email, size, speciality) { + super(email); + this.size = size; + this.speciality = speciality; + } +} + +export { + BaseOrder, + PizzaOrder +}; +*/ + +// Composición +const email = { email: '' }; +const size = { size: 'medium' }; +const speciality = { speciality: 'cheese' }; +const displayOrder = { + displayOrder: function () { + console.log('Order for: ' + this.email); + } +}; + +const BaseOrder = (params) => { + return Object.assign({}, email, displayOrder, params); +}; + +const toString = { + toString: function () { + return `${this.email} - ${this.size} - ${this.speciality}`; + } +}; + +const PizzaOrder = (params) => { + return Object.assign({}, email, size, speciality, displayOrder, toString, params); +}; + +export { + BaseOrder, + PizzaOrder +}; diff --git a/scripts-es6/store.js b/scripts-es6/store.js new file mode 100644 index 0000000..4d68713 --- /dev/null +++ b/scripts-es6/store.js @@ -0,0 +1,27 @@ +class Store { + constructor(storeId, db) { + this.storeId = storeId; + this.db = db; + } + + createOrder(order) { + console.log(`Adding order for ${order.email}`); + this.db.add(order.email, order); + } + + deliverOrder(email) { + console.log(`Delivering order for ${email}`); + this.db.remove(email); + } + + printOrders() { + const customerEmails = Object.keys(this.db.getAll()); + + console.log(`Store #${this.storeId} has pending orders`); + customerEmails.forEach((email) => { + console.log(this.db.get(email)); + }) + } +} + +export default Store; diff --git a/scripts/datastore.js b/scripts/datastore.js new file mode 100644 index 0000000..939fefe --- /dev/null +++ b/scripts/datastore.js @@ -0,0 +1,27 @@ +(function (window) { + 'use strict'; + var App = window.App || {}; + + function DataStore() { + this.data = {}; + } + + DataStore.prototype.add = function (key, val) { + this.data[key] = val; + }; + + DataStore.prototype.get = function (key) { + return this.data[key]; + }; + + DataStore.prototype.getAll = function () { + return this.data; + }; + + DataStore.prototype.remove = function (key) { + delete this.data[key]; + }; + + App.DataStore = DataStore; + window.App = App; +}(window)); // IIFE diff --git a/scripts/main.js b/scripts/main.js new file mode 100644 index 0000000..654ffc6 --- /dev/null +++ b/scripts/main.js @@ -0,0 +1,17 @@ +(function (window) { + 'use strict'; + var App = window.App; + var DataStore = App.DataStore; + var Store = App.Store; + var pizzaOrderFactory = App.pizzaOrderFactory; + + console.log('Pizza place'); + var dataStore = new DataStore(); + var store = new Store('ncc-1701', dataStore); + var order = pizzaOrderFactory('enrique@devcode.com', 'large', 'cheese'); + + store.createOrder(order); + order.displayOrder(); + store.printOrders(); + +}(window)); diff --git a/scripts/order.js b/scripts/order.js new file mode 100644 index 0000000..5687044 --- /dev/null +++ b/scripts/order.js @@ -0,0 +1,28 @@ +(function () { + 'use strict'; + var App = window.App || {}; + + var order = { + email: '', + displayOrder: function () { + console.log('Order for: ' + this.email); + } + }; + + function pizzaOrderFactory(email, size, speciality) { + return Object.create(order, { + email: { value: email }, + size: { value: size }, + speciality: { value: speciality }, + displayOrder: { + value: function() { + order.displayOrder.call(this); + console.log('Size: ' + this.size); + } + } + }); + } + + App.pizzaOrderFactory = pizzaOrderFactory; + window.App = App; +}()); diff --git a/scripts/store.js b/scripts/store.js new file mode 100644 index 0000000..85d228c --- /dev/null +++ b/scripts/store.js @@ -0,0 +1,40 @@ +(function () { + 'use strict'; + var App = window.App || {}; + + function Store(storeId, db) { + // this = {}; + // this.__proto__ = Store.prototype + this.storeId = storeId; + this.db = db; // composición + // return this; + } + + Store.prototype.createOrder = function (order) { + console.log('Adding order for: ' + order.email); + this.db.add(order.email, order); + }; + + Store.prototype.deliverOrder = function (email) { + console.log('Delivering order for: ' + email); + this.db.remove(email); + }; + + Store.prototype.printOrders = function () { + console.log('Store #' + this.storeId + ' has pending orders'); + + var customerEmails = Object.keys(this.db.getAll()); + // var self = this; + // customerEmails.forEach(function (email) { + // console.log(self.db.get(email)); + // }); + + customerEmails.forEach(function (email) { + console.log(this.db.get(email)); + }.bind(this)); + + }; + + App.Store = Store; + window.App = App; +}()); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..18166e7 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,41 @@ +const webpack = require('webpack'); +const path = require('path'); + +const nodeEnv = process.env.NODE_ENV || 'production'; + +module.exports = { + devtool: 'source-map', + entry: { + filename: './scripts-es6/main.js' + }, + output: { + filename: '_build/bundle.js' + }, + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader', + query: { + presets: ['es2015-native-modules'] + } + } + ] + }, + plugins: [ + // uglify js + new webpack.optimize.UglifyJsPlugin({ + compress: { warnings: false }, + output: { comments: false }, + sourceMap: true + }), + // env plugin + new webpack.DefinePlugin({ + 'proccess.env': { NODE_ENV: JSON.stringify(nodeEnv) } + }) + ], + devServer: { + contentBase: path.resolve(__dirname, './'), + } +};