diff --git a/package-lock.json b/package-lock.json index cce28b7..137b2d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,11 @@ "@babel/preset-env": "7.20.2", "babel-loader": "9.1.0", "copy-webpack-plugin": "11.0.0", + "css-loader": "6.7.2", "eslint": "8.28.0", "eslint-config-htmlacademy": "8.0.0", "html-webpack-plugin": "5.6.0", + "style-loader": "3.3.1", "webpack": "5.75.0", "webpack-cli": "5.0.0", "webpack-dev-server": "4.11.1" @@ -3161,6 +3163,44 @@ "node": ">= 8" } }, + "node_modules/css-loader": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", + "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.18", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", @@ -3189,6 +3229,18 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/dayjs": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", @@ -4676,6 +4728,18 @@ "node": ">=0.10.0" } }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -5440,6 +5504,24 @@ "multicast-dns": "cli.js" } }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5933,6 +6015,112 @@ "node": ">=8" } }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6672,6 +6860,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -6808,6 +7005,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9930,6 +10143,30 @@ "which": "^2.0.1" } }, + "css-loader": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", + "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.18", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "dependencies": { + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + } + } + }, "css-select": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", @@ -9949,6 +10186,12 @@ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, "dayjs": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", @@ -11053,6 +11296,13 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "requires": {} + }, "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -11593,6 +11843,12 @@ "thunky": "^1.0.2" } }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11959,6 +12215,69 @@ } } }, + "postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + } + }, + "postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12524,6 +12843,12 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true + }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -12633,6 +12958,13 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "requires": {} + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 8f454d6..34241c7 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,11 @@ "@babel/preset-env": "7.20.2", "babel-loader": "9.1.0", "copy-webpack-plugin": "11.0.0", + "css-loader": "6.7.2", "eslint": "8.28.0", "eslint-config-htmlacademy": "8.0.0", "html-webpack-plugin": "5.6.0", + "style-loader": "3.3.1", "webpack": "5.75.0", "webpack-cli": "5.0.0", "webpack-dev-server": "4.11.1" diff --git a/src/main.js b/src/main.js index 096a597..1d21208 100644 --- a/src/main.js +++ b/src/main.js @@ -1,24 +1,18 @@ import FilterView from './view/filter-view.js'; import SortView from './view/sort-view.js'; import ListPresenter from './presenter/list-presenter.js'; -import {render} from './render.js'; import PointsModel from './model/points-model.js'; -import DestinationsModel from './model/destinations-model.js'; -import OffersModel from './model/offers-model.js'; +import {render} from './framework/render.js'; const filterContainer = document.querySelector('.trip-controls__filters'); -const sortAndListContainer = document.querySelector('.trip-events'); +const pointsContainer = document.querySelector('.trip-events'); const pointsModel = new PointsModel(); -const destinationsModel = new DestinationsModel({pointsModel}); -const offersModel = new OffersModel({pointsModel}); const listPresenter = new ListPresenter({ - container: sortAndListContainer, - pointsModel: pointsModel, - destinationsModel: destinationsModel, - offersModel: offersModel + container: pointsContainer, + pointsModel }); render(new FilterView(), filterContainer); -render(new SortView(), sortAndListContainer); +render(new SortView(), pointsContainer); listPresenter.init(); diff --git a/src/mock/point.js b/src/mock/point.js index 3c5b9e4..becca55 100644 --- a/src/mock/point.js +++ b/src/mock/point.js @@ -129,8 +129,13 @@ function getOffersByType(type) { return offers.find((offersByType) => offersByType.type === type).offers; } -function getOfferById(offersByType, id) { - return offersByType.find((offer) => offer.id === id); +function getSelectedOffers(offerIds, offersByType) { + const selectedOffers = []; + for (let i = 0; i < offerIds.length; i++ ) { + selectedOffers.push(offersByType.find((offer) => offer.id === offerIds[i])); + } + + return selectedOffers; } -export {getRandomPoint, getDestinationById, getOffersByType, getOfferById}; +export {getRandomPoint, getDestinationById, getOffersByType, getSelectedOffers}; diff --git a/src/model/destinations-model.js b/src/model/destinations-model.js deleted file mode 100644 index 5a13eae..0000000 --- a/src/model/destinations-model.js +++ /dev/null @@ -1,13 +0,0 @@ -import {getDestinationById} from '../mock/point.js'; - -export default class DestinationsModel { - destinations = []; - - getDestinations(points) { - for (let i = 0; i < points.length; i++) { - this.destinations.push(getDestinationById(points[i].destination)); - } - - return this.destinations; - } -} diff --git a/src/model/offers-model.js b/src/model/offers-model.js deleted file mode 100644 index f68dc18..0000000 --- a/src/model/offers-model.js +++ /dev/null @@ -1,26 +0,0 @@ -import {getOffersByType, getOfferById} from '../mock/point.js'; - -export default class OffersModel { - selectedOffersList = []; - typesOffersList = []; - - getSelectedOffers(points) { - for (let i = 0; i < points.length; i++) { - const pointOffers = []; - const offersByType = getOffersByType(points[i].type); - const offersIdList = points[i].offers; - for (let j = 0; j < offersIdList.length; j++){ - pointOffers.push(getOfferById(offersByType, offersIdList[j])); - } - this.selectedOffersList.push(pointOffers); - } - return this.selectedOffersList; - } - - getTypesOffers(points) { - for (let i = 0; i < points.length; i++) { - this.typesOffersList.push(getOffersByType(points[i].type)); - } - return this.typesOffersList; - } -} diff --git a/src/model/points-model.js b/src/model/points-model.js index a0e4d7a..e123460 100644 --- a/src/model/points-model.js +++ b/src/model/points-model.js @@ -2,9 +2,9 @@ import {getRandomPoint} from '../mock/point.js'; import {POINT_COUNT} from '../const.js'; export default class PointsModel { - points = Array.from({length: POINT_COUNT}, getRandomPoint); + #points = Array.from({length: POINT_COUNT}, getRandomPoint); - getPoints() { - return this.points; + get points() { + return this.#points; } } diff --git a/src/presenter/list-presenter.js b/src/presenter/list-presenter.js index e61f2d7..a077e2c 100644 --- a/src/presenter/list-presenter.js +++ b/src/presenter/list-presenter.js @@ -1,30 +1,73 @@ import ListView from '../view/list-view.js'; import EditPointView from '../view/edit-point-view.js'; -import ListPointView from '../view/list-point-view.js'; -import {render} from '../render.js'; +import ListPointView from '../view/point-view.js'; +import {render, replace} from '../framework/render.js'; +import {getDestinationById, getOffersByType, getSelectedOffers} from '../mock/point.js'; export default class ListPresenter { - listComponent = new ListView(); + #listComponent = new ListView(); + #container; + #pointsModel; + #points; - constructor({container, pointsModel, destinationsModel, offersModel}) { - this.container = container; - this.pointsModel = pointsModel; - this.destinationsModel = destinationsModel; - this.offersModel = offersModel; + constructor({container, pointsModel}) { + this.#container = container; + this.#pointsModel = pointsModel; } init() { - this.points = [...this.pointsModel.getPoints()]; - this.destinations = [...this.destinationsModel.getDestinations(this.points)]; - this.selectedOffers = [...this.offersModel.getSelectedOffers(this.points)]; - this.typesOffers = [...this.offersModel.getTypesOffers(this.points)]; - render(this.listComponent, this.container); - render(new EditPointView({pointData: this.points[0], destinationData: this.destinations[0], offersByType: this.typesOffers[0]}), - this.listComponent.getElement()); - - for (let i = 1; i < this.points.length; i++) { - render(new ListPointView({pointData: this.points[i], destinationData: this.destinations[i], - selectedOffersData: this.selectedOffers[i]}), this.listComponent.getElement()); + this.#points = [...this.#pointsModel.points]; + render(this.#listComponent, this.#container); + + for (let i = 0; i < this.#points.length; i++) { + this.#renderPoint(this.#points[i]); } } + + #renderPoint(point) { + const escKeyDownHandler = (evt) => { + if (evt.key === 'Escape') { + evt.preventDefault(); + replaceEditFormToPoint(); + document.removeEventListener('keydown', escKeyDownHandler); + } + }; + + const offersByType = getOffersByType(point.type); + const destination = getDestinationById(point.destination); + + const pointComponent = new ListPointView({ + point, + destination, + selectedOffers: getSelectedOffers(point.offers, offersByType), + handleClick: () => { + replacePointToEditForm(); + document.addEventListener('keydown', escKeyDownHandler); + } + }); + + const pointEditComponent = new EditPointView({ + point, + destination, + offersByType, + handleSubmit: () => { + replaceEditFormToPoint(); + document.removeEventListener('keydown', escKeyDownHandler); + }, + handleClick: () => { + replaceEditFormToPoint(); + document.removeEventListener('keydown', escKeyDownHandler); + } + }); + + function replacePointToEditForm() { + replace(pointEditComponent, pointComponent); + } + + function replaceEditFormToPoint() { + replace(pointComponent, pointEditComponent); + } + + render(pointComponent, this.#listComponent.element); + } } diff --git a/src/render.js b/src/render.js deleted file mode 100644 index 8c22c92..0000000 --- a/src/render.js +++ /dev/null @@ -1,19 +0,0 @@ -const RenderPosition = { - BEFOREBEGIN: 'beforebegin', - AFTERBEGIN: 'afterbegin', - BEFOREEND: 'beforeend', - AFTEREND: 'afterend', -}; - -function createElement(template) { - const newElement = document.createElement('div'); - newElement.innerHTML = template; - - return newElement.firstElementChild; -} - -function render(component, container, place = RenderPosition.BEFOREEND) { - container.insertAdjacentElement(place, component.getElement()); -} - -export {RenderPosition, createElement, render}; diff --git a/src/view/edit-point-view.js b/src/view/edit-point-view.js index 1abb960..309ed82 100644 --- a/src/view/edit-point-view.js +++ b/src/view/edit-point-view.js @@ -1,5 +1,5 @@ -import {createElement} from '../render.js'; -import {TYPES, DESTINATIONS} from '../const.js'; +import {TYPES, DESTINATIONS, DEFAULT_POINT_DATA} from '../const.js'; +import AbstractView from '../framework/view/abstract-view.js'; function editPointTemplate(point, destination, typesTemplate, offersTemplate, picturesTemplate, destinationsTemplate) { return ` @@ -49,6 +49,9 @@ function editPointTemplate(point, destination, typesTemplate, offersTemplate, pi +
@@ -75,27 +78,38 @@ function editPointTemplate(point, destination, typesTemplate, offersTemplate, pi `; } -export default class EditPointView { - constructor({pointData, destinationData, offersByType}) { - this.pointData = pointData; - this.destinationData = destinationData; - this.offersByType = offersByType; +export default class EditPointView extends AbstractView { + #point; + #destination; + #offersByType; + #handleSubmit; + #handleClick; + + constructor({point = DEFAULT_POINT_DATA, destination, offersByType, handleSubmit, handleClick}) { + super(); + this.#point = point; + this.#destination = destination; + this.#offersByType = offersByType; + this.#handleSubmit = handleSubmit; + this.element.querySelector('form').addEventListener('submit', this.#submitHandler); + this.#handleClick = handleClick; + this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#clickHandler); } - getTypesTemplate() { + get #typesTemplate() { let typesTemplate = ''; for (let i = 0; i < TYPES.length; i++) { - const isChecked = TYPES[i] === this.pointData.type ? 'checked' : ''; + const isChecked = TYPES[i] === this.#point.type ? 'checked' : ''; typesTemplate += `
- - + +
`; } return typesTemplate; } - getDestinationsTemplate() { + get #destinationsTemplate() { let destinationsTemplate = ''; for (let i = 0; i < DESTINATIONS.length; i++) { destinationsTemplate += ` @@ -104,48 +118,46 @@ export default class EditPointView { return destinationsTemplate; } - getOffersTemplate() { + get #offersTemplate() { let offersTemplate = ''; - for (let i = 0; i < this.offersByType.length; i++) { - const isChecked = this.offersByType[i].id in this.pointData.offers ? 'checked' : ''; - const offerShortName = this.offersByType[i].name.toLowerCase().split(' ').at(-1); + for (let i = 0; i < this.#offersByType.length; i++) { + const isChecked = this.#offersByType[i].id in this.#point.offers ? 'checked' : ''; + const offerShortName = this.#offersByType[i].name.toLowerCase().split(' ').at(-1); offersTemplate += `
- -
`; } return offersTemplate; } - getPicturesTemplate() { + get #picturesTemplate() { let picturesTemplate = ''; - for (let i = 0; i < this.destinationData.pictures.length; i++) { - const picture = this.destinationData.pictures[i]; + for (let i = 0; i < this.#destination.pictures.length; i++) { + const picture = this.#destination.pictures[i]; picturesTemplate += ` ${picture.description}`; } return picturesTemplate; } - getTemplate() { - return editPointTemplate(this.pointData, this.destinationData, this.getTypesTemplate(), - this.getOffersTemplate(), this.getPicturesTemplate(), this.getDestinationsTemplate()); + get template() { + return editPointTemplate(this.#point, this.#destination, this.#typesTemplate, + this.#offersTemplate, this.#picturesTemplate, this.#destinationsTemplate); } - getElement() { - if (!this.element) { - this.element = createElement(this.getTemplate()); - } - - return this.element; - } + #submitHandler = (evt) => { + evt.preventDefault(); + this.#handleSubmit(); + }; - removeElement() { - this.element = null; - } + #clickHandler = (evt) => { + evt.preventDefault(); + this.#handleClick(); + }; } diff --git a/src/view/filter-view.js b/src/view/filter-view.js index e461319..fa1aae5 100644 --- a/src/view/filter-view.js +++ b/src/view/filter-view.js @@ -1,4 +1,4 @@ -import {createElement} from '../render.js'; +import AbstractView from '../framework/view/abstract-view.js'; function createFilterTemplate() { return ` @@ -28,20 +28,8 @@ function createFilterTemplate() { `; } -export default class FilterView { - getTemplate() { +export default class FilterView extends AbstractView { + get template() { return createFilterTemplate(); } - - getElement() { - if (!this.element) { - this.element = createElement(this.getTemplate()); - } - - return this.element; - } - - removeElement() { - this.element = null; - } } diff --git a/src/view/list-view.js b/src/view/list-view.js index 49f1c03..e584047 100644 --- a/src/view/list-view.js +++ b/src/view/list-view.js @@ -1,23 +1,11 @@ -import {createElement} from '../render.js'; +import AbstractView from '../framework/view/abstract-view.js'; function createListTemplate() { return ''; } -export default class ListView { - getTemplate() { +export default class ListView extends AbstractView { + get template() { return createListTemplate(); } - - getElement() { - if (!this.element) { - this.element = createElement(this.getTemplate()); - } - - return this.element; - } - - removeElement() { - this.element = null; - } } diff --git a/src/view/list-point-view.js b/src/view/point-view.js similarity index 62% rename from src/view/list-point-view.js rename to src/view/point-view.js index 1db74ab..9a181b3 100644 --- a/src/view/list-point-view.js +++ b/src/view/point-view.js @@ -1,5 +1,5 @@ -import {createElement} from '../render.js'; import {humanizeDueDate, humanizeDueTime, humanizeDuration} from '../utils.js'; +import AbstractView from '../framework/view/abstract-view.js'; function createListPointTemplate(point, totalPrice, destination, selectedOffersTemplate, isFavorite) { return ` @@ -39,51 +39,53 @@ function createListPointTemplate(point, totalPrice, destination, selectedOffersT `; } -export default class ListPointView { - constructor({pointData, destinationData, selectedOffersData}) { - this.pointData = pointData; - this.destinationData = destinationData; - this.selectedOffersData = selectedOffersData; +export default class ListPointView extends AbstractView { + #point; + #destination; + #selectedOffers; + #handleClick; + + constructor({point, destination, selectedOffers, handleClick}) { + super(); + this.#point = point; + this.#destination = destination; + this.#selectedOffers = selectedOffers; + this.#handleClick = handleClick; + this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#clickHandler); } - getSelectedOffersTemplate() { + get #selectedOffersTemplate() { let selectedOffersTemplate = ''; - for (let i = 0; i < this.selectedOffersData.length; i++) { + for (let i = 0; i < this.#selectedOffers.length; i++) { selectedOffersTemplate += `
  • - ${this.selectedOffersData[i].name} + ${this.#selectedOffers[i].name} +€  - ${this.selectedOffersData[i].price} + ${this.#selectedOffers[i].price}
  • `; } return selectedOffersTemplate; } - getTotalPrice() { - let totalPrice = this.pointData.basePrice; - for (let i = 0; i < this.selectedOffersData.length; i++) { - totalPrice += this.selectedOffersData[i].price; + get #totalPrice() { + let totalPrice = this.#point.basePrice; + for (let i = 0; i < this.#selectedOffers.length; i++) { + totalPrice += this.#selectedOffers[i].price; } return totalPrice; } - isFavorite() { - return this.pointData.isFavorite ? 'event__favorite-btn--active' : ''; + #isFavorite() { + return this.#point.isFavorite ? 'event__favorite-btn--active' : ''; } - getTemplate() { - return createListPointTemplate(this.pointData, this.getTotalPrice(), this.destinationData, - this.getSelectedOffersTemplate(), this.isFavorite()); + get template() { + return createListPointTemplate(this.#point, this.#totalPrice, this.#destination, + this.#selectedOffersTemplate, this.#isFavorite); } - getElement() { - if (!this.element) { - this.element = createElement(this.getTemplate()); - } - return this.element; - } - - removeElement() { - this.element = null; - } + #clickHandler = (evt) => { + evt.preventDefault(); + this.#handleClick(); + }; } diff --git a/src/view/sort-view.js b/src/view/sort-view.js index bd38720..6731c7c 100644 --- a/src/view/sort-view.js +++ b/src/view/sort-view.js @@ -1,4 +1,4 @@ -import {createElement} from '../render'; +import AbstractView from '../framework/view/abstract-view.js'; function createSortTemplate() { return ` @@ -31,20 +31,8 @@ function createSortTemplate() { `; } -export default class SortView { - getTemplate() { +export default class SortView extends AbstractView { + get template() { return createSortTemplate(); } - - getElement() { - if (!this.element) { - this.element = createElement(this.getTemplate()); - } - - return this.element; - } - - removeElement() { - this.element = null; - } } diff --git a/webpack.config.js b/webpack.config.js index 69f3597..e917a26 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -37,6 +37,10 @@ module.exports = { }, }, }, - ] - } + { + test: /\.css$/i, + use: ['style-loader', 'css-loader'] + }, + ], + }, };