diff --git a/hw7node/main.js b/hw7node/main.js new file mode 100644 index 0000000..e60a7ff --- /dev/null +++ b/hw7node/main.js @@ -0,0 +1,22 @@ +let products = [{"product_name": "Мышка", "price": 100}] + +const http = require ('http'); + +const server = http.createServer((req, res) => { + if(req.url === '/') { + res.write('Hello'); + res.end(); + } + + if(req.url === '/products') { + res.write(JSON.stringify(products)); + res.end(); + } +}) + +server.listen(3000); +server.on('connection', (socket) => { + console.log('New connection') +}); + +console.log('server listen at port 3000...'); \ No newline at end of file diff --git a/hw7node/package-lock.json b/hw7node/package-lock.json new file mode 100644 index 0000000..04b7f04 --- /dev/null +++ b/hw7node/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "hw7node", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + } + } +} diff --git a/hw7node/package.json b/hw7node/package.json new file mode 100644 index 0000000..75330f4 --- /dev/null +++ b/hw7node/package.json @@ -0,0 +1,14 @@ +{ + "name": "hw7node", + "version": "1.0.0", + "description": "", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "moment": "^2.24.0" + } +} diff --git a/hw7node/project/package-lock.json b/hw7node/project/package-lock.json new file mode 100644 index 0000000..8b396c4 --- /dev/null +++ b/hw7node/project/package-lock.json @@ -0,0 +1,363 @@ +{ + "name": "project", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + } + } +} diff --git a/hw7node/project/package.json b/hw7node/project/package.json new file mode 100644 index 0000000..91669fe --- /dev/null +++ b/hw7node/project/package.json @@ -0,0 +1,15 @@ +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.16.4", + "moment": "^2.24.0" + } +} diff --git a/hw7node/project/public/index.html b/hw7node/project/public/index.html new file mode 100644 index 0000000..d78f060 --- /dev/null +++ b/hw7node/project/public/index.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + e-Shop + + + +
+
+ +
+ + +
+
+
+ + +
+ + +
+ + + + + + + + + + + + + + + + + + diff --git a/hw7node/project/public/js/basketComponent.js b/hw7node/project/public/js/basketComponent.js new file mode 100644 index 0000000..e7d7468 --- /dev/null +++ b/hw7node/project/public/js/basketComponent.js @@ -0,0 +1,84 @@ +Vue.component('cart', { + data() { + return { + cartItems: [], + imgCart: 'https://placehold.it/50x100', + cartUrl: '/getBasket.json', + showCart: false, + } + }, + methods: { + addProduct(product) { + let find = this.cartItems.find(el => el.id_product === product.id_product); + if (find) { + this.$parent.putJson(`/api/cart/${find.id_product}`, { quantity: 1 }) + .then(data => { + if (data.result) { + find.quantity++; + } + }) + } else { + let prod = Object.assign({ quantity: 1 }, product); + this.$parent.postJson('/api/cart/', prod) + .then(data => { + if (data.result) { + this.cartItems.push(prod); + } + }) + } + }, + remove(product) { + let find = this.cartItems.find(el => el.id_product === product.id_product); + if (find && find.quantity > 1) { + this.$parent.putJson(`/api/cart/${find.id_product}`, { quantity: -1 }) + .then(data => { + if (data.result) { + if (product.quantity > 1) { + product.quantity--; + } + } + }) + } else { + this.$parent.deleteJson(`/api/cart/${find.id_product}`) + this.cartItems.splice(this.cartItems.indexOf(product), 1); + } + }, + }, + mounted() { + this.$parent.getJson(`/api/cart`) + .then(data => { + for (let el of data.contents) { + this.cartItems.push(el); + } + }); + }, + template: `
+ +
+

Cart is empty

+ +
+
` +}); +Vue.component('cart-item', { + props: ['cartItem', 'img'], + template: `
+
+ Some image +
+

{{cartItem.product_name}}

+

Quantity: {{cartItem.quantity}}

+

$ {{cartItem.price}} each

+
+
+
+

{{cartItem.quantity*cartItem.price}}

+ +
+
` +}) diff --git a/hw7node/project/public/js/errorComponent.js b/hw7node/project/public/js/errorComponent.js new file mode 100644 index 0000000..34808e0 --- /dev/null +++ b/hw7node/project/public/js/errorComponent.js @@ -0,0 +1,19 @@ +Vue.component('error', { + data(){ + return { + text: '' + } + }, + methods: { + setError(error){ + this.text = error + } + }, + template: `
+

+ + + {{ text }} +

+
` +}); diff --git a/hw7node/project/public/js/productComponent.js b/hw7node/project/public/js/productComponent.js new file mode 100644 index 0000000..bb11156 --- /dev/null +++ b/hw7node/project/public/js/productComponent.js @@ -0,0 +1,51 @@ +Vue.component('products', { + data(){ + return { + filtered: [], + products: [], + imgCatalog: 'https://placehold.it/200x150', + catalogUrl: '/catalogData.json' + } + }, + mounted(){ + this.$parent.getJson(`/api/products`) + .then(data => { + for(let el of data){ + this.products.push(el); + this.filtered.push(el); + } + }); + // this.$parent.getJson(`getProducts.json`) + // .then(data => { + // for(let el of data){ + // this.products.push(el); + // this.filtered.push(el); + // } + // }); + }, + methods: { + filter(value){ + let regexp = new RegExp(value, 'i'); + this.filtered = this.products.filter(el => regexp.test(el.product_name)); + } + }, + template: `
+ +
` +}); + +Vue.component('product', { + props: ['product', 'img'], + template: `
+ Some img +
+

{{ product.product_name }}

+

{{ product.price }} $

+ +
+
` +}) diff --git a/hw7node/project/public/js/script.js b/hw7node/project/public/js/script.js new file mode 100644 index 0000000..6065db1 --- /dev/null +++ b/hw7node/project/public/js/script.js @@ -0,0 +1,63 @@ +const API = 'https://raw.githubusercontent.com/GeekBrainsTutorial/online-store-api/master/responses'; + +let app = new Vue({ + el: '#app', + methods: { + getJson(url){ + return fetch(url) + .then(result => result.json()) + .catch(error => { + this.$refs.error.setError(error); + console.log(error) + }) + }, + postJson(url, data){ + return fetch(url, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data) + }) + .then(result => result.json()) + .catch(error => { + this.$refs.error.setError(error); + console.log(error) + }) + }, + putJson(url, data){ + return fetch(url, { + method: 'PUT', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data) + }) + .then(result => result.json()) + .catch(error => { + this.$refs.error.setError(error); + console.log(error) + }) + }, + deleteJson(url, data){ + return fetch(url, { + method: 'DELETE', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data) + }) + .then(result => result.json()) + .catch(error => { + this.$refs.error.setError(error); + console.log(error) + }) + }, + + }, + mounted(){ + + + + } +}) diff --git a/hw7node/project/public/js/searchComponent.js b/hw7node/project/public/js/searchComponent.js new file mode 100644 index 0000000..8640bc9 --- /dev/null +++ b/hw7node/project/public/js/searchComponent.js @@ -0,0 +1,14 @@ +Vue.component('filter-el', { + data(){ + return { + userSearch: '', + } + }, + template: `
+ + +
` + }); + \ No newline at end of file diff --git a/hw7node/project/public/styles/normalize.css b/hw7node/project/public/styles/normalize.css new file mode 100644 index 0000000..8c331ec --- /dev/null +++ b/hw7node/project/public/styles/normalize.css @@ -0,0 +1,350 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + + html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + } + + /* Sections + ========================================================================== */ + + /** + * Remove the margin in all browsers. + */ + + body { + margin: 0; + } + + /** + * Render the `main` element consistently in IE. + */ + + main { + display: block; + } + + /** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + + h1 { + font-size: 2em; + margin: 0.67em 0; + } + + /* Grouping content + ========================================================================== */ + + /** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + + hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ + } + + /** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + + pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ + } + + /* Text-level semantics + ========================================================================== */ + + /** + * Remove the gray background on active links in IE 10. + */ + + a { + background-color: transparent; + } + + /** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + + abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ + } + + /** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + + b, + strong { + font-weight: bolder; + } + + /** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + + code, + kbd, + samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ + } + + /** + * Add the correct font size in all browsers. + */ + + small { + font-size: 80%; + } + + /** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + + sub, + sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + + sub { + bottom: -0.25em; + } + + sup { + top: -0.5em; + } + + /* Embedded content + ========================================================================== */ + + /** + * Remove the border on images inside links in IE 10. + */ + + img { + border-style: none; + } + + /* Forms + ========================================================================== */ + + /** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + + button, + input, + optgroup, + select, + textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ + } + + /** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + + button, + input { /* 1 */ + overflow: visible; + } + + /** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + + button, + select { /* 1 */ + text-transform: none; + } + + /** + * Correct the inability to style clickable types in iOS and Safari. + */ + + button, + [type="button"], + [type="reset"], + [type="submit"] { + -webkit-appearance: button; + } + + /** + * Remove the inner border and padding in Firefox. + */ + + button::-moz-focus-inner, + [type="button"]::-moz-focus-inner, + [type="reset"]::-moz-focus-inner, + [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; + } + + /** + * Restore the focus styles unset by the previous rule. + */ + + button:-moz-focusring, + [type="button"]:-moz-focusring, + [type="reset"]:-moz-focusring, + [type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; + } + + /** + * Correct the padding in Firefox. + */ + + fieldset { + padding: 0.35em 0.75em 0.625em; + } + + /** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + + legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ + } + + /** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + + progress { + vertical-align: baseline; + } + + /** + * Remove the default vertical scrollbar in IE 10+. + */ + + textarea { + overflow: auto; + } + + /** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + + [type="checkbox"], + [type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + } + + /** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + + [type="number"]::-webkit-inner-spin-button, + [type="number"]::-webkit-outer-spin-button { + height: auto; + } + + /** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + + [type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ + } + + /** + * Remove the inner padding in Chrome and Safari on macOS. + */ + + [type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + } + + /** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + + ::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ + } + + /* Interactive + ========================================================================== */ + + /* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + + details { + display: block; + } + + /* + * Add the correct display in all browsers. + */ + + summary { + display: list-item; + } + + /* Misc + ========================================================================== */ + + /** + * Add the correct display in IE 10+. + */ + + template { + display: none; + } + + /** + * Add the correct display in IE 10. + */ + + [hidden] { + display: none; + } + \ No newline at end of file diff --git a/hw7node/project/public/styles/style.css b/hw7node/project/public/styles/style.css new file mode 100644 index 0000000..008f02f --- /dev/null +++ b/hw7node/project/public/styles/style.css @@ -0,0 +1,198 @@ +body{ + font-family: 'SF Pro Display', sans-serif; +} +header{ + display: flex; + background-color: #2f2a2d; + justify-content: space-between; + color: #fafafa; + padding: 30px 80px; +} +button:focus{ + outline: none; +} +.logo{ + + text-transform: uppercase; + font-weight: bold; +} +.btn-cart{ + background-color: #fafafa; + padding: 10px 20px; + border: 1px solid transparent; + color: #2f2a2d; + border-radius: 5px; + transition: all ease-in-out .4s; + cursor: pointer; +} +.btn-cart:hover{ + background-color: transparent; + border-color: #fafafa; + color: #fafafa; +} +.btn-cart, .logo{ + align-self: center; +} +/*.products {*/ +/*display: flex;*/ +/*justify-content: space-between;*/ +/*flex-wrap: wrap;*/ +/*padding: 40px 80px;*/ +/*}*/ +.products{ + column-gap: 30px; + display: grid; + grid-template-columns: repeat(auto-fit, 200px); + grid-template-rows: 1fr; + padding: 40px 80px; + justify-content: space-between; +} +p { + margin: 0 0 5px 0; +} +.product-item{ + display: flex; + flex-direction: column; + width: 200px; + border-radius: 5px; + overflow: hidden; + margin: 20px 0; +} +img { + max-width: 100%; + height: auto +} +.desc { + border: 1px solid #c0c0c040; + padding: 15px +} +.cart{ + display: flex; + position: relative; +} +.cart-block{ + box-shadow: 0 0 5px rgba(0, 0, 0, 0.62); + border-radius: 5px; + box-sizing: border-box; + right: 0; + top: 130%; + position: absolute; + background-color: white; + padding: 20px; + color: black; + width: 300px; +} + +.invisible{ + display: none; +} +.cart-block:before{ + content: ''; + width: 0; + height: 0; + position: absolute; + top: -10px; + right: 35px; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 10px solid white; +} + +.buy-btn, .del-btn{ + margin-top: 5px; + background-color: #2f2a2d; + padding: 5px 15px; + border: 1px solid transparent; + color: #fafafa; + border-radius: 5px; + transition: all ease-in-out .4s; + cursor: pointer; +} +.buy-btn:hover, .del-btn:hover{ + background-color: #fafafa; + color: #2f2a2d; + border: 1px solid #2f2a2d; +} +.cart-item { + display: flex; + justify-content: space-between; +} +.cart-item:not(:last-child){ + margin-bottom: 20px; +} +.product-bio{ + display: flex; +} +.cart-item img{ + align-self: flex-start; + margin-right: 15px; +} +.product-single-price{ + color: #474747; + font-size: 0.5em; +} +.product-price{ + margin-left: 30px; +} +.product-desc{ + max-width: 150px; +} +.product-quantity { + margin-top: 15px; + font-size: 0.75em; +} +.right-block{ + text-align: right; +} +.btn-search { + background-color: transparent; + border: none; + color: #fafafa; + font-size: 1.2em; + position: absolute; + bottom: 5px; + right: 0; +} +.search-form{ + position: relative; + margin-right: 50px; + display: inline-block; +} +.search-field:focus{ + outline: none; +} +.search-field { + box-sizing: border-box; + width: 200px; + color: #fafafa; + padding: 10px; + background-color: transparent; + border: none; + border-bottom: 2px solid #fafafa; +} +.error-msg { + padding: 30px 20px; + background-color: red; + color: white; + position: relative; +} +.error-block { + background-color: rgba(0,0,0, .5); + justify-content: center; + display: flex; + position: absolute; + top: 0; + width: 100%; + height: 100%; + align-items: center; +} +.close-btn { + font-size: 1.5em; + top: -40px; + position: absolute; + right: 0; + background: none; + border: none; + color: white; + font-weight: bold; +} diff --git a/hw7node/project/server/cart.js b/hw7node/project/server/cart.js new file mode 100644 index 0000000..4fc81d5 --- /dev/null +++ b/hw7node/project/server/cart.js @@ -0,0 +1,20 @@ +let add = (cart, req) => { + cart.contents.push (req.body); + return JSON.stringify(cart, null, 4); +} + +let change = (cart, req) => { + let find = cart.contents.find(el => el.id_product === +req.params.id); + find.quantity += req.body.quantity; + return JSON.stringify(cart, null, 4); +} + +let remove = (cart, req) => { + let find = cart.contents.find(el => el.id_product === +req.params.id); + cart.contents.splice(cart.contents.indexOf(find), 1); + return JSON.stringify(cart, null, 4); +} + +module.exports = { + add, change, remove +} \ No newline at end of file diff --git a/hw7node/project/server/db/products.json b/hw7node/project/server/db/products.json new file mode 100644 index 0000000..8d546ba --- /dev/null +++ b/hw7node/project/server/db/products.json @@ -0,0 +1,42 @@ +[ + { + "id_product": 124, + "product_name": "Keyboard", + "price": 1600 + }, + { + "id_product": 457, + "product_name": "Gamepad", + "price": 3000 + }, + { + "id_product": 129, + "product_name": "Notebook", + "price": 160000 + }, + { + "id_product": 458, + "product_name": "Display", + "price": 12000 + }, + { + "id_product": 224, + "product_name": "USB-Camera", + "price": 2400 + }, + { + "id_product": 228, + "product_name": "Scaner", + "price": 6000 + }, + { + "id_product": 123, + "product_name": "Ноутбук", + "price": 45600 + }, + { + "id_product": 456, + "product_name": "Мышка", + "price": 1000 + } +] \ No newline at end of file diff --git a/hw7node/project/server/db/userCart.json b/hw7node/project/server/db/userCart.json new file mode 100644 index 0000000..01531c9 --- /dev/null +++ b/hw7node/project/server/db/userCart.json @@ -0,0 +1,5 @@ +{ + "amount": 46600, + "countGoods": 2, + "contents": [] +} \ No newline at end of file diff --git a/hw7node/project/server/handler.js b/hw7node/project/server/handler.js new file mode 100644 index 0000000..17a5985 --- /dev/null +++ b/hw7node/project/server/handler.js @@ -0,0 +1,27 @@ +const cart = require('./cart'); +const fs = require('fs'); + +const actions = { + add: cart.add, + change: cart.change, + remove: cart.remove +}; + +let handler = (req, res, action, file) => { + fs.readFile(file, 'utf8', (err, data) => { + if (err) { + res.sendStatus(404, JSON.stringify({ result: 0, text: err })); + } else { + let newCart = actions[action](JSON.parse(data), req); + fs.writeFile(file, newCart, (err) => { + if (err) { + res.sendStatus(404, JSON.stringify({ result: 0, text: err })); + } else { + res.send({ result: 1, text: 'success' }); + } + }) + } + }) +} + +module.exports = handler; \ No newline at end of file diff --git a/hw7node/project/server/server.js b/hw7node/project/server/server.js new file mode 100644 index 0000000..ae30f56 --- /dev/null +++ b/hw7node/project/server/server.js @@ -0,0 +1,53 @@ +//в экспрессе мы получаем особые методы отлова запросов +// +// app.get(); +// app.post(); +// app.put(); +// app.delete(); + + +const express = require('express'); +const fs = require('fs'); +const app = express(); +app.use(express.json ());//определение json запроса +app.use('/', express.static('public')); + +app.get('/api/products', (req, res) => { + fs.readFile('server/db/products.json', 'utf8', (err, data) => { + if (err) { + res.sendStatus(404, JSON.stringify({result: 0, text: err})); + } else { + res.send(data); + } + }); +}); + +app.get('/api/cart', (req, res) => { + fs.readFile('server/db/userCart.json', 'utf8', (err, data) => { + if (err) { + res.sendStatus(404, JSON.stringify({result: 0, text: err})); + } else { + res.send(data); + } + }); +}); + +const handler = require('./handler'); + +app.post ('/api/cart/', (req, res) => { + handler(req, res, 'add', 'server/db/userCart.json'); +}); + +app.put ('/api/cart/:id', (req, res) => { + handler(req, res, 'change', 'server/db/userCart.json'); +}); + +app.delete ('/api/cart/:id', (req, res) => { + handler(req, res, 'remove', 'server/db/userCart.json'); +}); + + +app.listen(3000, () => ('listening at port 3000...')); + + +