From 16e8208298fb9d83cd806d254c905f89200d8d47 Mon Sep 17 00:00:00 2001 From: Darya Palitsyna Date: Tue, 7 May 2024 15:40:10 +0500 Subject: [PATCH 1/6] =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B5=D0=B7=D0=B5=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=BE=D1=87=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/presenter/point-presenter.js | 76 ++++++++++++++++++++++++++++++++ src/presenter/trip-presenter.js | 74 ++++++++++--------------------- 2 files changed, 99 insertions(+), 51 deletions(-) create mode 100644 src/presenter/point-presenter.js diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js new file mode 100644 index 0000000..045085c --- /dev/null +++ b/src/presenter/point-presenter.js @@ -0,0 +1,76 @@ +import { remove, render, replace } from "../framework/render"; +import ListPointsView from "../view/list-points-view"; +import EditPointView from "../view/editing-form-view"; + +export default class PointPresenter { + #pointListContainer = null; + + #pointComponent = null; + #pointEditComponent = null; + + #destinationsModel = null; + #offersModel = null; + + #point = null; + + constructor({pointListContainer, destinationsModel, offersModel}) { + this.#pointListContainer = pointListContainer; + this.#destinationsModel = destinationsModel; + this.#offersModel = offersModel; + } + + init(point) { + this.#point = point; + + const prevPointComponent = this.#pointComponent; + const prevPointEditComponent = this.#pointEditComponent; + + this.#pointComponent = new ListPointsView({ + data: this.#point, + destinations: this.#destinationsModel.getDestinationById(point.destinations), + offers: this.#offersModel.getOffersByType(point.type), + onEditClick: pointEditClickHandler + }) + + this.#pointEditComponent = new EditPointView({ + point: this.#point, + pointDestinations: this.#destinationsModel.get(), + pointOffers: this.#offersModel.get(), + onResetClick: resetButtonClickHandler, + onSubmitClick: pointSubmitHandler + }) + + function replaceEditToPoint() { + replace(prevPointComponent, prevPointEditComponent); + } + + function replacePointToEdit() { + replace(prevPointEditComponent, prevPointComponent); + } + + const escKeyDown = (evt) => { + if (evt.key === 'Escape' || evt.key === 'Esc') { + evt.preventDefault(); + replaceEditToPoint(); + document.removeEventListener('keydown', escKeyDown); + } + }; + + function pointEditClickHandler() { + replacePointToEdit(); + document.addEventListener('keydown', escKeyDown); + } + + function resetButtonClickHandler() { + replaceEditToPoint(); + document.removeEventListener('keydown', escKeyDown); + } + + function pointSubmitHandler() { + replaceEditToPoint(); + document.removeEventListener('keydown', escKeyDown); + } + + /* render(pointComponent, this.#pointListContainer.element); */ + } +} diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index f020b87..79b13ea 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -1,8 +1,7 @@ -import EditPointView from '../view/editing-form-view.js'; -import ListPointsView from '../view/list-points-view.js'; import ListView from '../view/list-view.js'; import EventListEmptyView from '../view/event-list-empty-view.js'; -import {render, replace} from '../framework/render.js'; +import {render, remove} from '../framework/render.js'; +import PointPresenter from './point-presenter.js'; export default class TripPresenter { #listComponent = new ListView(); @@ -24,63 +23,36 @@ export default class TripPresenter { } init() { - if (this.#tripPoint.length === 0) { - render(new EventListEmptyView(), this.#listContainer); - return; - } - - this.currentPoint = this.#pointsModel.points; - - render(this.#listComponent,this.#listContainer); - - this.#tripPoint.forEach((point) => { - this.#renderPoint(point); - }); + this.#renderBoard(); } #renderPoint(point) { - const pointComponent = new ListPointsView ({ - data: point, - onEditClick: pointEditClickHandler + const pointPresenter = new PointPresenter({ + pointListContainer: this.#listComponent.element, }); - const editingForm = new EditPointView({ - point, - onSubmitClick: pointSubmitHandler, - onResetClick: resetButtonClickHandler - }); - - function replaceEditToPoint() { - replace(pointComponent, editingForm); - } + pointPresenter.init(point); + }; - function replacePointToEdit() { - replace(editingForm, pointComponent); - } - - const escKeyDown = (evt) => { - if (evt.key === 'Escape' || evt.key === 'Esc') { - evt.preventDefault(); - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); - } - }; + #renderPoints = () => { + this.#tripPoint.forEach((point) => { + this.#renderPoint(point); + }); + }; - function pointEditClickHandler() { - replacePointToEdit(); - document.addEventListener('keydown', escKeyDown); - } + #renderPointContainer = () => { + this.currentPoint = this.#pointsModel.points; - function resetButtonClickHandler() { - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); - } + render(this.#listComponent,this.#listContainer); + } - function pointSubmitHandler() { - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); + #renderBoard = () => { + if (this.#tripPoint.length === 0) { + render(new EventListEmptyView(), this.#listContainer); + return; } - render(pointComponent, this.#listComponent.element); - } + this.#renderPointContainer(); + this.#renderPoints(); + }; } From cbdd8b709ab22e6c2fb7c356f5c80dbe403dd6e8 Mon Sep 17 00:00:00 2001 From: Darya Palitsyna Date: Wed, 15 May 2024 19:29:34 +0500 Subject: [PATCH 2/6] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/const.js | 6 +- src/mock/destination.js | 136 +++++++++++++++++++-- src/mock/offer.js | 197 +++++++++++++++++++++++++++++-- src/mock/point.js | 144 +++++++++++++++++++--- src/model/destination-model.js | 12 +- src/model/offer-model.js | 4 +- src/model/point-model.js | 6 +- src/presenter/point-presenter.js | 5 +- src/view/list-points-view.js | 10 +- 9 files changed, 463 insertions(+), 57 deletions(-) diff --git a/src/const.js b/src/const.js index d79292b..4c407df 100644 --- a/src/const.js +++ b/src/const.js @@ -1,5 +1,5 @@ -const DESTINATION_COUNT = 5; -const POINT_COUNT = 5; +const DESTINATION_COUNT = 7; +const POINTS_COUNT = 9; const OFFERS_COUNT = 5; const DEFAULT_TYPE = 'taxi'; @@ -64,4 +64,4 @@ const FilterType = [{ PAST: 'past' }]; -export {POINT_EMPTY, POINT_TYPE, DESTINATION, DESCRIPTION, OFFERS, DESTINATION_COUNT, OFFERS_COUNT, POINT_COUNT, FilterType}; +export {POINT_EMPTY, POINT_TYPE, DESTINATION, DESCRIPTION, OFFERS, DESTINATION_COUNT, OFFERS_COUNT, POINTS_COUNT, FilterType}; diff --git a/src/mock/destination.js b/src/mock/destination.js index e0d90fa..78f19b3 100644 --- a/src/mock/destination.js +++ b/src/mock/destination.js @@ -1,20 +1,132 @@ import { getRandomArrayElement } from '../utils/common'; -import { DESTINATION, DESCRIPTION } from '../const'; -function getRandomDestination() { - const sity = getRandomArrayElement(DESTINATION); - - return { - id: crypto.randomUUID(), - description: DESCRIPTION, - name: sity, +const destinations = +[ + { + id: "fb59a2fb-aaba-48b2-a70f-aeec93f4cf2e", + description: "Paris - with crowded streets", + name: "Paris", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/20.jpg", + description: "Paris with a beautiful old town" + } + ] + }, + { + id: "e58c23c2-364c-4987-a1ca-491b4fd6f2e6", + description: "Barcelona - is a beautiful city", + name: "Barcelona", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/9.jpg", + description: "Barcelona with crowded streets" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/20.jpg", + description: "Barcelona with an embankment of a mighty river as a centre of attraction" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/17.jpg", + description: "Barcelona with an embankment of a mighty river as a centre of attraction" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/9.jpg", + description: "Barcelona middle-eastern paradise" + } + ] + }, + { + id: "8cb872d0-b8fa-46d3-bfb2-9f17f41659bc", + description: "Moscow - a true asian pearl", + name: "Moscow", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/7.jpg", + description: "Moscow with crowded streets" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/9.jpg", + description: "Moscow is a beautiful city" + } + ] + }, + { + id: "3593993f-e3cb-41d1-a9ac-966d7d3f238f", + description: "Berlin - for those who value comfort and coziness", + name: "Berlin", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/9.jpg", + description: "Berlin middle-eastern paradise" + } + ] + }, + { + id: "bc8d6002-f60b-4196-b3b3-9549b62f323a", + description: "Amsterdam - full of of cozy canteens where you can try the best coffee in the Middle East", + name: "Amsterdam", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/4.jpg", + description: "Amsterdam a perfect place to stay with a family" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/14.jpg", + description: "Amsterdam with crowded streets" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/5.jpg", + description: "Amsterdam a true asian pearl" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/12.jpg", + description: "Amsterdam a perfect place to stay with a family" + } + ] + }, + { + id: "49ac16cb-176b-4d14-859c-d230d731811d", + description: "Rotterdam - famous for its crowded street markets with the best street food in Asia", + name: "Rotterdam", + pictures: [ + { + src: "https://21.objects.htmlacademy.pro/static/destinations/5.jpg", + description: "Rotterdam full of of cozy canteens where you can try the best coffee in the Middle East" + } + ] + }, + { + id: "0496fab3-92ec-43a0-9d3d-c82d17def782", + description: "Munich - a perfect place to stay with a family", + name: "Munich", pictures: [ { - 'src': `https://loremflickr.com/248/152?random=${crypto.randomUUID()}`, - 'description': `${sity} description` + src: "https://21.objects.htmlacademy.pro/static/destinations/13.jpg", + description: "Munich middle-eastern paradise" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/11.jpg", + description: "Munich in a middle of Europe" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/16.jpg", + description: "Munich famous for its crowded street markets with the best street food in Asia" + }, + { + src: "https://21.objects.htmlacademy.pro/static/destinations/9.jpg", + "description": "Munich in a middle of Europe" } ] - }; + } +] + +function getRandomDestination() { + return getRandomArrayElement(destinations); +} + +function getAllDestinations() { + destinations; } -export {getRandomDestination}; +export {getRandomDestination, getAllDestinations}; diff --git a/src/mock/offer.js b/src/mock/offer.js index 57dc4bd..6106cd2 100644 --- a/src/mock/offer.js +++ b/src/mock/offer.js @@ -1,12 +1,189 @@ -import { getRandomArrayElement, getRandomValue } from '../utils/common'; -import { OFFERS } from '../const'; - -function generateOffer() { - return { - id: crypto.randomUUID(), - title: getRandomArrayElement(OFFERS), - price: getRandomValue(), - }; +import { getRandomArrayElement } from '../utils/common'; + +const offers = +[ + { + type: "taxi", + offers: [ + { + id: 'fff61b86-4a48-4406-a072-96775b21f084', + title: "Upgrade to a business class", + price: 174 + }, + { + id: "50aaa585-7cee-4359-a593-0d722870d0cf", + title: "Choose the radio station", + price: 96 + }, + { + id: "6c7e9808-ba71-4abb-9c91-46f4dbd2e8c2", + title: "Choose temperature", + price: 76 + }, + { + id: "a5d3c2f8-b055-4c08-ab66-fee37d5466b4", + title: "Drive quickly, I'm in a hurry", + price: 166 + }, + { + id: "c59fcb6e-fcde-484b-94a7-31a04f33fb2c", + title: "Drive slowly", + price: 194 + } + ] + }, + { + type: "bus", + offers: [ + { + id: "3e33e7df-afa8-41df-9778-690eedd2a3a9", + title: "Infotainment system", + price: 116 + }, + { + id: "2d0c6c39-3f07-4676-aa7f-281d4c37a4a5", + title: "Order meal", + price: 66 + }, + { + id: "2163d3f6-89cf-4b87-999b-39dee574cd59", + title: "Choose seats", + price: 81 + } + ] + }, + { + type: "train", + offers: [ + { + id: "543073a1-1f5b-4662-870a-ebff50adeb4a", + title: "Book a taxi at the arrival point", + price: 38 + }, + { + id: "44326448-2406-475b-9a9b-885754ea74a7", + title: "Order a breakfast", + price: 104 + }, + { + id: "c40aa58f-b5a9-41f4-999f-341ccf8898c1", + title: "Wake up at a certain time", + price: 167 + } + ] + }, + { + type: "flight", + offers: [ + { + id: "cc5a07f6-747f-4803-9880-ba6be75fec14", + title: "Choose meal", + price: 124 + }, + { + id: "f35aff8f-c793-4f53-8e24-23631101ccb5", + title: "Choose seats", + price: 183 + }, + { + id: "18963e62-0ff2-4a9b-9809-eb3e941658bc", + title: "Upgrade to comfort class", + price: 93 + }, + { + id: "961fa89a-1e5a-4e7a-873f-8d66428cdb27", + title: "Upgrade to business class", + price: 117 + }, + { + id: "1b59a95f-4570-4447-9347-8fdef991de96", + title: "Add luggage", + price: 156 + }, + { + id: "74016829-fe16-4c1d-988d-3d1b6d06c36a", + title: "Business lounge", + price: 200 + } + ] + }, + { + type: "check-in", + offers: [ + { + id: "37b653b1-7b0b-4127-b981-7a8ea4201527", + title: "Choose the time of check-in", + price: 180 + }, + { + id: "867036e6-6110-4a02-9c14-1a428263c505", + title: "Choose the time of check-out", + price: 131 + }, + { + id: "2faf1c38-9a97-42ba-a59c-c18a49be81b3", + title: "Add breakfast", + price: 102 + }, + { + id: "32e839d4-e29d-49ff-b92d-2a9afead503b", + title: "Laundry", + price: 156 + }, + { + id: "3815fc7e-a4b3-4064-89bc-702794cff2f5", + title: "Order a meal from the restaurant", + price: 65 + } + ] + }, + { + type: "sightseeing", + offers: [] + }, + { + type: "ship", + offers: [ + { + id: "4bd06aa5-5d57-42c0-a601-50270eeeb7ca", + title: "Choose meal", + price: 135 + }, + { + id: "4154f7f6-f108-45cc-b38f-9947b8a31351", + title: "Choose seats", + price: 171 + }, + { + id: "9604fb2c-8452-4a61-91e3-25d65a1f3586", + title: "Upgrade to comfort class", + price: 200 + }, + { + id: "39be9fb7-efc9-4885-8963-569321e34e7f", + title: "Upgrade to business class", + price: 104 + }, + { + id: "933edee5-1cc9-41c5-abb2-61f3047a6a3e", + title: "Add luggage", + price: 96 + }, + { + id: "27965e6d-dee2-4cfa-9b68-476351460034", + title: "Business lounge", + price: 196 + } + ] + } +] + +function getRandomOffer() { + return getRandomArrayElement(offers); +} + +function getAllOffers() { + return offers; } -export {generateOffer}; +export {getRandomOffer, getAllOffers}; diff --git a/src/mock/point.js b/src/mock/point.js index 2dfec5f..ec2eb2d 100644 --- a/src/mock/point.js +++ b/src/mock/point.js @@ -1,17 +1,133 @@ -import { getRandomArrayElement, getRandomValue } from '../utils/common.js'; -import { POINT_TYPE } from '../const.js'; +import { getRandomArrayElement } from '../utils/common.js'; -function generatePoint(destinationId, offersIds) { - return { - id: crypto.randomUUID(), - basePrice: getRandomValue(), - dateFrom: '2019-07-10T22:55:56.845Z', - dateTo: '2019-07-11T11:22:13.375Z', - destination: destinationId, - isFavorite: getRandomArrayElement([0,1]), - offers: offersIds, - type: getRandomArrayElement(POINT_TYPE) - }; +const points = [ + { + id: "f5a9215b-77a1-4a2b-89e7-d34f6da80b4e", + basePrice: 6008, + dateFrom: "2024-05-05T16:32:07.283Z", + dateTo: "2024-05-07T14:51:07.283Z", + destination: "bc8d6002-f60b-4196-b3b3-9549b62f323a", + isFavorite: true, + offers: [], + type: "sightseeing" + }, + { + id: "3ca35f81-52b1-4e2f-bc5c-ee57c53edec3", + basePrice: 3503, + dateFrom: "2024-05-09T02:21:07.283Z", + dateTo: "2024-05-09T22:52:07.283Z", + destination: "e58c23c2-364c-4987-a1ca-491b4fd6f2e6", + isFavorite: false, + offers: [ + "c40aa58f-b5a9-41f4-999f-341ccf8898c1" + ], + type: "train" + }, + { + id: "e6aec202-de66-4959-85e6-fa0e5d711423", + basePrice: 2755, + dateFrom: "2024-05-11T20:51:07.283Z", + dateTo: "2024-05-13T15:33:07.283Z", + destination: "49ac16cb-176b-4d14-859c-d230d731811d", + isFavorite: true, + offers: [ + "961fa89a-1e5a-4e7a-873f-8d66428cdb27", + "1b59a95f-4570-4447-9347-8fdef991de96", + "74016829-fe16-4c1d-988d-3d1b6d06c36a" + ], + type: "flight" + }, + { + id: "3da72a5e-1426-4585-8c9b-21874eec93ee", + basePrice: 9690, + dateFrom: "2024-05-15T02:39:07.283Z", + dateTo: "2024-05-17T01:33:07.283Z", + destination: "518190c3-81f6-4bd1-91f6-a8f63c6ce7f0", + isFavorite: false, + offers: [ + "c40aa58f-b5a9-41f4-999f-341ccf8898c1" + ], + type: "train" + }, + { + id: "c8b03b49-7f75-47d9-8759-21c3b99247f2", + basePrice: 1550, + dateFrom: "2024-05-19T01:12:07.283Z", + dateTo: "2024-05-19T10:36:07.283Z", + destination: "bc8d6002-f60b-4196-b3b3-9549b62f323a", + "is_favorite": true, + offers: [ + "961fa89a-1e5a-4e7a-873f-8d66428cdb27", + "1b59a95f-4570-4447-9347-8fdef991de96", + "74016829-fe16-4c1d-988d-3d1b6d06c36a" + ], + type: "flight" + }, + { + id: "4dd3dbd9-a542-4c6a-980e-2e454255a906", + basePrice: 2121, + dateFrom: "2024-05-21T05:25:07.283Z", + dateTo: "2024-05-22T00:02:07.283Z", + destination: "5269a40c-e37c-4370-bd05-a9903491d66b", + isFavorite: true, + offers: [ + "961fa89a-1e5a-4e7a-873f-8d66428cdb27", + "1b59a95f-4570-4447-9347-8fdef991de96", + "74016829-fe16-4c1d-988d-3d1b6d06c36a" + ], + type: "flight" + }, + { + id: "a6dcea28-ad66-4bde-a5a7-db3e5b6142d2", + basePrice: 8477, + dateFrom: "2024-05-23T07:59:07.283Z", + dateTo: "2024-05-24T01:15:07.283Z", + destination: "9978fc13-8912-4e31-8059-b3e37039c3b7", + isFavorite: true, + offers: [ + "4bd06aa5-5d57-42c0-a601-50270eeeb7ca", + "4154f7f6-f108-45cc-b38f-9947b8a31351", + "9604fb2c-8452-4a61-91e3-25d65a1f3586", + "39be9fb7-efc9-4885-8963-569321e34e7f", + "933edee5-1cc9-41c5-abb2-61f3047a6a3e", + "27965e6d-dee2-4cfa-9b68-476351460034" + ], + type: "ship" + }, + { + id: "9be435b5-33e0-425d-8396-85bb1e26c379", + basePrice: 4060, + dateFrom: "2024-05-25T10:57:07.283Z", + dateTo: "2024-05-27T01:53:07.283Z", + destination: "9978fc13-8912-4e31-8059-b3e37039c3b7", + isFavorite: false, + offers: [], + type: "sightseeing" + }, + { + id: "031c39fa-20ab-4f2f-be8a-18473e77c9c8", + basePrice: 4950, + dateFrom: "2024-05-28T14:09:07.283Z", + dateTo: "2024-05-29T19:52:07.283Z", + destination: "49ac16cb-176b-4d14-859c-d230d731811d", + isFavorite: false, + offers: [ + "f35aff8f-c793-4f53-8e24-23631101ccb5", + "18963e62-0ff2-4a9b-9809-eb3e941658bc", + "961fa89a-1e5a-4e7a-873f-8d66428cdb27", + "1b59a95f-4570-4447-9347-8fdef991de96", + "74016829-fe16-4c1d-988d-3d1b6d06c36a" + ], + type: "flight" + } +] + +function getRandomPoint() { + return getRandomArrayElement(points); +} + +function getAllPoints() { + return points; } -export {generatePoint}; +export {getRandomPoint, getAllPoints}; diff --git a/src/model/destination-model.js b/src/model/destination-model.js index 51de6fc..38b5f03 100644 --- a/src/model/destination-model.js +++ b/src/model/destination-model.js @@ -1,23 +1,23 @@ -import { getRandomDestination } from '../mock/destination'; +import { getRandomDestination, getAllDestinations } from '../mock/destination'; import { DESTINATION_COUNT } from '../const'; export default class DestinationModel { - #destinations = Array.from({length: DESTINATION_COUNT}, () => getRandomDestination); + #destination = Array.from({length: DESTINATION_COUNT}, () => getRandomDestination()); get destinations() { - return this.#destinations; + return this.#destination; } getDestinationByType(type) { - const destination = this.#destinations.find((dest) => dest.type === type); + const destination = this.#destination.find((dest) => dest.type === type); if (destination) { - return destination.destinations; + return destination.destination; } return null; } getDestinationById(id) { - return this.#destinations.find((destination) => destination.id === id); + return this.#destination.find((dest) => dest.id === id); } } diff --git a/src/model/offer-model.js b/src/model/offer-model.js index b17204e..7a26007 100644 --- a/src/model/offer-model.js +++ b/src/model/offer-model.js @@ -1,11 +1,11 @@ -import { generateOffer } from '../mock/offer'; +import { getRandomOffer } from '../mock/offer'; import { OFFERS_COUNT, OFFERS } from '../const'; import { getRandomValue } from '../utils/common'; export default class OffersModel { #allOffers = OFFERS.map((type) => ({ type, - offers: Array.from({ length: getRandomValue(0, OFFERS_COUNT) }, () => generateOffer()) + offers: Array.from({ length: getRandomValue(0, OFFERS_COUNT) }, () => getRandomOffer()) })); get allOffers() { diff --git a/src/model/point-model.js b/src/model/point-model.js index 6bd8468..69436fa 100644 --- a/src/model/point-model.js +++ b/src/model/point-model.js @@ -1,8 +1,8 @@ -import { generatePoint } from '../mock/point'; -import { POINT_COUNT } from '../const'; +import { getRandomPoint, getAllPoints } from '../mock/point'; +import { POINTS_COUNT } from '../const'; export default class PointsModel { - #points = Array.from({length: POINT_COUNT}, () => generatePoint()); + #points = Array.from({length: POINTS_COUNT }, () => getRandomPoint()); get points() { return this.#points; diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js index 045085c..0c5b4c6 100644 --- a/src/presenter/point-presenter.js +++ b/src/presenter/point-presenter.js @@ -1,6 +1,7 @@ import { remove, render, replace } from "../framework/render"; import ListPointsView from "../view/list-points-view"; import EditPointView from "../view/editing-form-view"; +import DestinationModel from "../model/destination-model"; export default class PointPresenter { #pointListContainer = null; @@ -26,8 +27,8 @@ export default class PointPresenter { const prevPointEditComponent = this.#pointEditComponent; this.#pointComponent = new ListPointsView({ - data: this.#point, - destinations: this.#destinationsModel.getDestinationById(point.destinations), + point: this.#point, + destination: this.#destinationsModel.getDestinationById(point.destination), offers: this.#offersModel.getOffersByType(point.type), onEditClick: pointEditClickHandler }) diff --git a/src/view/list-points-view.js b/src/view/list-points-view.js index e57f25d..c735bd3 100644 --- a/src/view/list-points-view.js +++ b/src/view/list-points-view.js @@ -4,14 +4,14 @@ import { POINT_EMPTY } from '../const.js'; export default class ListPointsView extends AbstractView { #point = null; - #destinations = null; + #destination = null; #offers = null; #onEditClick = null; - constructor ({data = POINT_EMPTY, destinations, offers, onEditClick}) { + constructor ({point = POINT_EMPTY, destination, offers, onEditClick}) { super(); - this.#point = data; - this.#destinations = destinations; + this.#point = point; + this.#destination = destination; this.#offers = offers; this.#onEditClick = onEditClick; @@ -23,7 +23,7 @@ export default class ListPointsView extends AbstractView { get template() { return createListPointsTemplate({ point: this.#point, - destinations: this.#destinations, + destination: this.#destination, offers: this.#offers }); } From c0a10ff64a279733b827b220c07112698924955d Mon Sep 17 00:00:00 2001 From: Darya Palitsyna Date: Sun, 19 May 2024 19:33:29 +0500 Subject: [PATCH 3/6] =?UTF-8?q?=D0=9D=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BF=D1=80=D0=B5=D0=B7=D0=B5=D0=BD=D1=82=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 47 ++++++++++++++++++++++++-------- package.json | 3 +- src/framework/render.js | 2 +- src/main.js | 12 ++++---- src/mock/destination.js | 2 +- src/presenter/point-presenter.js | 43 +++++++++++++++++++++++------ src/presenter/trip-presenter.js | 31 +++++++++++++++------ src/view/editing-form-view.js | 2 +- src/view/list-points-view.js | 13 ++++++++- 9 files changed, 115 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7663ec5..216668c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,8 @@ "name": "big-trip", "version": "19.0.0", "dependencies": { - "dayjs": "1.11.10" + "dayjs": "1.11.10", + "nanoid": "^5.0.7" }, "devDependencies": { "@babel/core": "^7.20.5", @@ -5496,10 +5497,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", "funding": [ { "type": "github", @@ -5507,10 +5507,10 @@ } ], "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^18 || >=20" } }, "node_modules/natural-compare": { @@ -6112,6 +6112,24 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/postcss/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/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11793,10 +11811,9 @@ } }, "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==" }, "natural-compare": { "version": "1.4.0", @@ -12173,6 +12190,14 @@ "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.2.0" + }, + "dependencies": { + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + } } }, "postcss-modules-extract-imports": { diff --git a/package.json b/package.json index e4ffd90..86d8629 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "node": "18" }, "dependencies": { - "dayjs": "1.11.10" + "dayjs": "1.11.10", + "nanoid": "^5.0.7" } } diff --git a/src/framework/render.js b/src/framework/render.js index 2e089db..0b3d410 100644 --- a/src/framework/render.js +++ b/src/framework/render.js @@ -31,7 +31,7 @@ function render(component, container, place = RenderPosition.BEFOREEND) { throw new Error('Can render only components'); } - if (container === null) { + if (!container) { throw new Error('Container element doesn\'t exist'); } diff --git a/src/main.js b/src/main.js index 453e346..bbab2ab 100644 --- a/src/main.js +++ b/src/main.js @@ -3,7 +3,7 @@ import TripInfoView from './view/trip-info-view.js'; import SortPointsView from './view/sort-points-view.js'; import TripPresenter from './presenter/trip-presenter.js'; -import {render, RenderPosition} from './framework/render.js'; +import { render, RenderPosition } from './framework/render.js'; import PointsModel from './model/point-model.js'; import DestinationModel from './model/destination-model.js'; @@ -11,13 +11,11 @@ import OffersModel from './model/offer-model.js'; import { generateFilters } from './mock/filter.js'; - const filterHeaderElement = document.querySelector('.trip-controls'); const siteFilterElement = filterHeaderElement.querySelector('.trip-controls__filters'); const siteMainElement = document.querySelector('.page-main'); const siteSortElement = siteMainElement.querySelector('.trip-events'); const tripInfoElement = document.querySelector('.trip-main'); -/* const tripPresenter = new TripPresenter({listContainer: siteSortElement}); */ const pointsModel = new PointsModel(); const destinationModel = new DestinationModel(); @@ -25,15 +23,15 @@ const offersModel = new OffersModel(); const tripPresenter = new TripPresenter({ listContainer: siteSortElement, - destinationModel, - offersModel, - pointsModel + pointsModel, + destinationsModel: destinationModel, + offersModel }); const filters = generateFilters(pointsModel.points); render(new SortPointsView(), siteSortElement); -render(new FilterPointsView({filters}), siteFilterElement); +render(new FilterPointsView({ filters }), siteFilterElement); render(new TripInfoView(), tripInfoElement, RenderPosition.AFTERBEGIN); tripPresenter.init(); diff --git a/src/mock/destination.js b/src/mock/destination.js index 78f19b3..3bfd109 100644 --- a/src/mock/destination.js +++ b/src/mock/destination.js @@ -126,7 +126,7 @@ function getRandomDestination() { } function getAllDestinations() { - destinations; + return destinations; } export {getRandomDestination, getAllDestinations}; diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js index 0c5b4c6..8fddfce 100644 --- a/src/presenter/point-presenter.js +++ b/src/presenter/point-presenter.js @@ -6,15 +6,21 @@ import DestinationModel from "../model/destination-model"; export default class PointPresenter { #pointListContainer = null; - #pointComponent = null; - #pointEditComponent = null; + #pointComponent; + #pointEditComponent; #destinationsModel = null; #offersModel = null; #point = null; - constructor({pointListContainer, destinationsModel, offersModel}) { + constructor({ pointListContainer, destinationsModel, offersModel }) { + console.log('PointPresenter constructor:', { pointListContainer, destinationsModel, offersModel }); + + if (!pointListContainer || !pointListContainer instanceof Element) { + throw new Error('Invalid pointListContainer or its element'); + } + this.#pointListContainer = pointListContainer; this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; @@ -26,20 +32,29 @@ export default class PointPresenter { const prevPointComponent = this.#pointComponent; const prevPointEditComponent = this.#pointEditComponent; + console.log('Init point:', point); + console.log('Destinations Model:', this.#destinationsModel); + this.#pointComponent = new ListPointsView({ point: this.#point, destination: this.#destinationsModel.getDestinationById(point.destination), offers: this.#offersModel.getOffersByType(point.type), - onEditClick: pointEditClickHandler - }) + onEditClick: pointEditClickHandler, + /* onFavoriteClick: */ + }); this.#pointEditComponent = new EditPointView({ point: this.#point, - pointDestinations: this.#destinationsModel.get(), - pointOffers: this.#offersModel.get(), + pointDestinations: this.#destinationsModel.destinations, + pointOffers: this.#offersModel.allOffers, onResetClick: resetButtonClickHandler, onSubmitClick: pointSubmitHandler - }) + }); + + if (!prevPointComponent || !prevPointEditComponent) { + render(this.#pointComponent, this.#pointListContainer); + return; + } function replaceEditToPoint() { replace(prevPointComponent, prevPointEditComponent); @@ -72,6 +87,16 @@ export default class PointPresenter { document.removeEventListener('keydown', escKeyDown); } - /* render(pointComponent, this.#pointListContainer.element); */ + /* function pointFavoriteHandler() { + + } */ + + console.log('Rendering point component to:', this.#pointListContainer); + render(this.#pointComponent, this.#pointListContainer); + } + + destroy() { + remove(this.#pointComponent); + remove(this.#pointEditComponent); } } diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index 79b13ea..8e2642a 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -1,7 +1,9 @@ import ListView from '../view/list-view.js'; import EventListEmptyView from '../view/event-list-empty-view.js'; -import {render, remove} from '../framework/render.js'; +import { render, remove } from '../framework/render.js'; import PointPresenter from './point-presenter.js'; +import DestinationModel from '../model/destination-model.js'; +import OffersModel from '../model/offer-model.js'; export default class TripPresenter { #listComponent = new ListView(); @@ -13,7 +15,9 @@ export default class TripPresenter { #tripPoint = []; - constructor({listContainer, pointsModel, destinationsModel, offersModel}) { + #pointPresenters = new Map(); + + constructor({ listContainer, pointsModel, destinationsModel, offersModel }) { this.#listContainer = listContainer; this.#pointsModel = pointsModel; this.#destinationsModel = destinationsModel; @@ -27,26 +31,32 @@ export default class TripPresenter { } #renderPoint(point) { + if (!this.#listComponent.element) { + throw new Error('List component element is not defined'); + } + const pointPresenter = new PointPresenter({ pointListContainer: this.#listComponent.element, + destinationsModel: this.#destinationsModel, + offersModel: this.#offersModel }); pointPresenter.init(point); - }; + this.#pointPresenters.set(point.id, pointPresenter); + } #renderPoints = () => { this.#tripPoint.forEach((point) => { this.#renderPoint(point); }); - }; + } #renderPointContainer = () => { - this.currentPoint = this.#pointsModel.points; - - render(this.#listComponent,this.#listContainer); + render(this.#listComponent, this.#listContainer); } #renderBoard = () => { + console.log('Rendering board'); if (this.#tripPoint.length === 0) { render(new EventListEmptyView(), this.#listContainer); return; @@ -54,5 +64,10 @@ export default class TripPresenter { this.#renderPointContainer(); this.#renderPoints(); - }; + } + + #clearPointsList() { + this.#pointPresenters.forEach((presenter) => presenter.destroy()); + this.#pointPresenters.clear(); + } } diff --git a/src/view/editing-form-view.js b/src/view/editing-form-view.js index 904b795..f7dbdfc 100644 --- a/src/view/editing-form-view.js +++ b/src/view/editing-form-view.js @@ -41,6 +41,6 @@ export default class EditPointView extends AbstractView { #resetButtonClickHandler = (evt) => { evt.preventDefalt(); - this.#onResetClick(); + this.#onResetClick(this.#point); }; } diff --git a/src/view/list-points-view.js b/src/view/list-points-view.js index c735bd3..f8c812c 100644 --- a/src/view/list-points-view.js +++ b/src/view/list-points-view.js @@ -7,17 +7,23 @@ export default class ListPointsView extends AbstractView { #destination = null; #offers = null; #onEditClick = null; + #onFavoriteClick = null; - constructor ({point = POINT_EMPTY, destination, offers, onEditClick}) { + constructor ({point = POINT_EMPTY, destination, offers, onEditClick, onFavoriteClick}) { super(); this.#point = point; this.#destination = destination; this.#offers = offers; this.#onEditClick = onEditClick; + this.#onFavoriteClick = onFavoriteClick; this.element .querySelector('.event__rollup-btn') .addEventListener('click', this.#editButtonClickHandler); + + this.element + .querySelector('.event__favorite-btn') + .addEventListener('click', this.#favoriteButtonClickHandler); } get template() { @@ -32,4 +38,9 @@ export default class ListPointsView extends AbstractView { evt.preventDefault(); this.#onEditClick(); }; + + #favoriteButtonClickHandler = (evt) => { + evt.preventDefault(); + this.#onFavoriteClick(); + } } From 94fc6e790d74a3d4499a26e1e46e464317aa4ce0 Mon Sep 17 00:00:00 2001 From: Darya Palitsyna Date: Sun, 19 May 2024 22:35:56 +0500 Subject: [PATCH 4/6] =?UTF-8?q?5.8.=20=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D1=8B=20(?= =?UTF-8?q?=D1=87=D0=B0=D1=81=D1=82=D1=8C=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/presenter/point-presenter.js | 98 ++++++++++++++++++---------- src/presenter/trip-presenter.js | 12 ++++ src/template/list-points-template.js | 4 +- src/utils/common.js | 6 +- src/view/editing-form-view.js | 2 +- 5 files changed, 84 insertions(+), 38 deletions(-) diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js index 8fddfce..3687cf7 100644 --- a/src/presenter/point-presenter.js +++ b/src/presenter/point-presenter.js @@ -3,6 +3,11 @@ import ListPointsView from "../view/list-points-view"; import EditPointView from "../view/editing-form-view"; import DestinationModel from "../model/destination-model"; +const Mode = { + DEFAULT: 'DEFAULT', + EDITING: 'EDITING', +}; + export default class PointPresenter { #pointListContainer = null; @@ -12,9 +17,13 @@ export default class PointPresenter { #destinationsModel = null; #offersModel = null; + #handleDataChange = null; + #handleModeChange = null; + #point = null; + #mode = Mode.DEFAULT; - constructor({ pointListContainer, destinationsModel, offersModel }) { + constructor({ pointListContainer, destinationsModel, offersModel, onDataChange, onModeChange }) { console.log('PointPresenter constructor:', { pointListContainer, destinationsModel, offersModel }); if (!pointListContainer || !pointListContainer instanceof Element) { @@ -24,6 +33,8 @@ export default class PointPresenter { this.#pointListContainer = pointListContainer; this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; + this.#handleDataChange = onDataChange; + this.#handleModeChange = onModeChange; } init(point) { @@ -39,16 +50,16 @@ export default class PointPresenter { point: this.#point, destination: this.#destinationsModel.getDestinationById(point.destination), offers: this.#offersModel.getOffersByType(point.type), - onEditClick: pointEditClickHandler, - /* onFavoriteClick: */ + onEditClick: this.#pointEditClickHandler, + onFavoriteClick: this.#pointFavoriteHandler }); this.#pointEditComponent = new EditPointView({ point: this.#point, pointDestinations: this.#destinationsModel.destinations, pointOffers: this.#offersModel.allOffers, - onResetClick: resetButtonClickHandler, - onSubmitClick: pointSubmitHandler + onResetClick: this.#resetButtonClickHandler, + onSubmitClick: this.#handleFormSubmit }); if (!prevPointComponent || !prevPointEditComponent) { @@ -56,47 +67,64 @@ export default class PointPresenter { return; } - function replaceEditToPoint() { - replace(prevPointComponent, prevPointEditComponent); + if (this.#mode === Mode.DEFAULT) { + replace(this.#pointComponent, prevPointComponent) } - - function replacePointToEdit() { - replace(prevPointEditComponent, prevPointComponent); + if (this.#mode === Mode.EDITING) { + replace(this.#pointEditComponent, prevPointEditComponent); } - const escKeyDown = (evt) => { - if (evt.key === 'Escape' || evt.key === 'Esc') { - evt.preventDefault(); - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); - } - }; - - function pointEditClickHandler() { - replacePointToEdit(); - document.addEventListener('keydown', escKeyDown); - } + remove(prevPointComponent); + remove(prevPointEditComponent); + console.log('Rendering point component to:', this.#pointListContainer); + } - function resetButtonClickHandler() { - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); + destroy() { + remove(this.#pointComponent); + remove(this.#pointEditComponent); + } + + resetView() { + if (this.#mode !== Mode.DEFAULT) { + this.#replaceEditToPoint(); } + } - function pointSubmitHandler() { - replaceEditToPoint(); - document.removeEventListener('keydown', escKeyDown); + #escKeyDownHandler = (evt) => { + if (evt.key === 'Escape' || evt.key === 'Esc') { + evt.preventDefault(); + this.#replaceEditToPoint(); } + } - /* function pointFavoriteHandler() { + #replacePointToEdit() { + replace(this.#pointEditComponent, this.#pointComponent); + document.addEventListener('keydown', this.#escKeyDownHandler); - } */ + this.#handleModeChange(); + this.#mode = Mode.EDITING; + } - console.log('Rendering point component to:', this.#pointListContainer); - render(this.#pointComponent, this.#pointListContainer); + #replaceEditToPoint () { + replace(this.#pointComponent, this.#pointEditComponent); + document.removeEventListener('keydown', this.#escKeyDownHandler); + this.#mode = Mode.DEFAULT; } - destroy() { - remove(this.#pointComponent); - remove(this.#pointEditComponent); + #handleFormSubmit = (point) => { + this.#handleDataChange(point); + this.#replaceEditToPoint(); + } + + #pointEditClickHandler = () => { + this.#replacePointToEdit(); + } + + #resetButtonClickHandler = () => { + replaceEditToPoint(); + } + + #pointFavoriteHandler = () => { + this.#handleDataChange({...this.#point, isFavorite: !this.#point.isFavorite}) } } diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index 8e2642a..4b847bd 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -2,6 +2,7 @@ import ListView from '../view/list-view.js'; import EventListEmptyView from '../view/event-list-empty-view.js'; import { render, remove } from '../framework/render.js'; import PointPresenter from './point-presenter.js'; +import { updateItem } from '../utils/common.js'; import DestinationModel from '../model/destination-model.js'; import OffersModel from '../model/offer-model.js'; @@ -37,6 +38,8 @@ export default class TripPresenter { const pointPresenter = new PointPresenter({ pointListContainer: this.#listComponent.element, + onDataChange: this.#handlePointChange, + onModeChange: this.#handleModeChange, destinationsModel: this.#destinationsModel, offersModel: this.#offersModel }); @@ -70,4 +73,13 @@ export default class TripPresenter { this.#pointPresenters.forEach((presenter) => presenter.destroy()); this.#pointPresenters.clear(); } + + #handleModeChange = () => { + this.#pointPresenters.forEach((presenter) => presenter.resetView()); + } + + #handlePointChange = (updatePoint) => { + this.#tripPoint = updateItem(this.#tripPoint, updatePoint); + this.#pointPresenters.get(updatePoint.id).init(updatePoint); + } } diff --git a/src/template/list-points-template.js b/src/template/list-points-template.js index 9f11f93..71ace05 100644 --- a/src/template/list-points-template.js +++ b/src/template/list-points-template.js @@ -10,6 +10,8 @@ function createOffers(offers) { } function createListPointsTemplate({point, destinations, offers}) { + const isActiveClassName = point.isFavorite ? 'event__favorite-btn--active' : ''; + return `
@@ -31,7 +33,7 @@ function createListPointsTemplate({point, destinations, offers}) {
    ${createOffers(offers)}
-