From 816bc9b68922cff997a6f0f92ef40192880b4c2c Mon Sep 17 00:00:00 2001 From: Rudovsky Egor Date: Thu, 9 May 2024 19:37:00 +0500 Subject: [PATCH] =?UTF-8?q?6.6.=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B5=D0=BA=D0=B0=20(=D1=87?= =?UTF-8?q?=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/const.js | 2 +- src/mock/offers.js | 21 +++- src/model/destinations-model.js | 4 + src/model/offers-model.js | 4 + src/presenter/trip-events-presenter.js | 16 ++-- src/presenter/trip-point-presenter.js | 30 ++++-- src/util.js | 8 +- src/view/editable-point-view.js | 128 +++++++++++++++++++------ src/view/point-view.js | 11 ++- 9 files changed, 168 insertions(+), 56 deletions(-) diff --git a/src/const.js b/src/const.js index f18646e..5ecd470 100644 --- a/src/const.js +++ b/src/const.js @@ -1,5 +1,5 @@ const POINT_TYPE = ['taxi', 'bus', 'train', 'ship', 'drive', 'flight', 'check-in', 'sightseeing', 'restaurant']; -const CITIES = ['Amsterdam', 'Geneva', 'Chamonix', ]; +const CITIES = ['Amsterdam', 'Geneva', 'Chamonix', 'Moscow', 'Paris']; const DESCRIPTIONS = [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Cras aliquet varius magna, non porta ligula feugiat eget.', diff --git a/src/mock/offers.js b/src/mock/offers.js index 8768c6c..a064aad 100644 --- a/src/mock/offers.js +++ b/src/mock/offers.js @@ -9,6 +9,11 @@ const offers = [ id: 'of1', title: 'Upgrade', price: getRandomInteger(MIN_PRICE, MAX_PRICE) + }, + { + id: 'of0', + title: 'NoCheked', + price: 0 }] }, { @@ -28,7 +33,21 @@ const offers = [ title: 'First Class', price: getRandomInteger(MIN_PRICE, MAX_PRICE) }] - } + }, + { + type: 'train', + offers: [ + { + id: 'of8765', + title: 'Upgrade', + price: getRandomInteger(MIN_PRICE, MAX_PRICE) + }, + { + id: 'of34567654', + title: 'NoCheked', + price: 0 + }] + }, ]; export {offers}; diff --git a/src/model/destinations-model.js b/src/model/destinations-model.js index c06f0c3..f67c083 100644 --- a/src/model/destinations-model.js +++ b/src/model/destinations-model.js @@ -10,4 +10,8 @@ export default class DestinationsModel { getDestinationById(id){ return this.#destinations.find((destination) => destination.id === id); } + + getDestinationByName(name){ + return this.#destinations.find((destination) => destination.name === name); + } } diff --git a/src/model/offers-model.js b/src/model/offers-model.js index 4c888be..5242272 100644 --- a/src/model/offers-model.js +++ b/src/model/offers-model.js @@ -10,4 +10,8 @@ export default class OffersModel { getOfferByType(type){ return this.#offers.find((offer) => offer.type === type); } + + getOfferById(id){ + return this.#offers.find((offer) =>offer.id === id); + } } diff --git a/src/presenter/trip-events-presenter.js b/src/presenter/trip-events-presenter.js index b47c537..fda9b74 100644 --- a/src/presenter/trip-events-presenter.js +++ b/src/presenter/trip-events-presenter.js @@ -5,7 +5,7 @@ import ListEmptyView from '../view/list-empty-view.js'; import TripPointPresenter from './trip-point-presenter.js'; import {render} from '../framework/render.js'; import {LIST_EMPTY_TEXT} from '../const.js'; -import { calculateDateDifference } from '../util.js'; +import { calculateDateDifference, updateItem } from '../util.js'; export default class TripEventsPresenter { @@ -47,12 +47,10 @@ export default class TripEventsPresenter { } } - #changePointFavorite = (point) => { - this.#points = this.#points.map((element) => element.id === point.id ? point : element); + #handlePointChange = (updatedPoint) => { + this.#points = updateItem(this.#points, updatedPoint); - const destination = this.#destinationsModel.getDestinationById(point.destination); - const offer = this.#offersModel.getOfferByType(point.type); - this.#pointPresenters.get(point.id).init(point, destination, offer); + this.#pointPresenters.get(updatedPoint.id).init(updatedPoint); }; #changeSortType = (type) => { @@ -109,10 +107,8 @@ export default class TripEventsPresenter { for (let i = 0; i < points.length; i++) { const point = points[i]; - const destination = this.#destinationsModel.getDestinationById(point.destination); - const offer = this.#offersModel.getOfferByType(point.type); - const pointPresenter = new TripPointPresenter(this.#listComponent.element, this.#changePointFavorite, this.#changeViewHandler); - pointPresenter.init(point, destination, offer); + const pointPresenter = new TripPointPresenter(this.#listComponent.element, this.#changeViewHandler, this.#handlePointChange, this.#offersModel, this.#destinationsModel); + pointPresenter.init(point); this.#pointPresenters.set(point.id, pointPresenter); } }; diff --git a/src/presenter/trip-point-presenter.js b/src/presenter/trip-point-presenter.js index 7016325..2c02009 100644 --- a/src/presenter/trip-point-presenter.js +++ b/src/presenter/trip-point-presenter.js @@ -11,25 +11,34 @@ const VIEW = { export default class TripPointPresenter { #pointContainer = null; - #onFavoriteChange = null; #onViewChange = null; + #onDataChange = null; #pointComponent = null; #editPointComponent = null; + #offersModel = null; + #destinationsModel = null; + #point = null; #view = VIEW.DEFAULT; - constructor(pointContainer, onFavoriteChange, onViewChange) { + constructor(pointContainer, onViewChange, onDataChange, offersModel, destinationsModel) { this.#pointContainer = pointContainer; - this.#onFavoriteChange = onFavoriteChange; this.#onViewChange = onViewChange; + this.#onDataChange = onDataChange; + + this.#offersModel = offersModel; + this.#destinationsModel = destinationsModel; } - init(point, destination, offer) { + init(point) { this.#point = point; + const destination = this.#destinationsModel.getDestinationById(this.#point.destination); + const offer = this.#offersModel.getOfferByType(this.#point.type); + const prevPointComponent = this.#pointComponent; this.#pointComponent = new PointView({ @@ -46,7 +55,9 @@ export default class TripPointPresenter { offer, onDeleteButtonClick: this.#deleteButtonClikHandler, onSubmitForm: this.#submitFormHandler, - onRollupButtonClick: this.#formRollupButtonClikHandler + onRollupButtonClick: this.#formRollupButtonClikHandler, + getDestinationByName: this.#getDestinationByName, + getOfferByType : this.#getOfferByType }); if (prevPointComponent !== null && this.#pointContainer.contains(prevPointComponent.element)) { @@ -58,7 +69,7 @@ export default class TripPointPresenter { } #favoriteButtonClickHandler = () => { - this.#onFavoriteChange({...this.#point, isFavorite: !this.#point.isFavorite}); + this.#onDataChange({...this.#point, isFavorite: !this.#point.isFavorite}); }; #replacePointToForm() { @@ -93,7 +104,8 @@ export default class TripPointPresenter { document.removeEventListener('keydown', this.#onFormKeydown); }; - #submitFormHandler = () => { + #submitFormHandler = (point) => { + this.#onDataChange(point); this.#replaceFormToPoint(); document.removeEventListener('keydown', this.#onFormKeydown); }; @@ -109,4 +121,8 @@ export default class TripPointPresenter { this.#replaceFormToPoint(); } }; + + #getOfferByType = (type) => this.#offersModel.getOfferByType(type); + + #getDestinationByName = (name) => this.#destinationsModel.getDestinationByName(name); } diff --git a/src/util.js b/src/util.js index a0e958f..378877a 100644 --- a/src/util.js +++ b/src/util.js @@ -19,6 +19,10 @@ function createId() { }; } +function updateItem(items, update) { + return items.map((item) => item.id === update.id ? update : item); +} + function getRandomInteger(a, b) { const lower = Math.ceil(Math.min(a, b)); const upper = Math.floor(Math.max(a, b)); @@ -33,10 +37,10 @@ function calculateDateDifference(start, end) { return end.diff(start, 'minute'); } -const isElementHas = (element) => element.length > 0; +const isElementHas = (element) => element !== null && element !== undefined && element.length > 0; const getRandomArrayElement = (arr) => arr[getRandomInteger(0, arr.length - 1)]; const isEscapeKey = (evt) => evt.key === 'Escape'; -export {createId, getRandomInteger, getRandomArrayElement, formatEventDate, isElementHas, isEscapeKey, calculateDateDifference, formatEventDuration}; +export {createId, getRandomInteger, getRandomArrayElement, formatEventDate, isElementHas, isEscapeKey, calculateDateDifference, formatEventDuration, updateItem}; diff --git a/src/view/editable-point-view.js b/src/view/editable-point-view.js index 019f43b..53be7f4 100644 --- a/src/view/editable-point-view.js +++ b/src/view/editable-point-view.js @@ -1,11 +1,11 @@ -import { POINT_TYPE } from '../const.js'; +import { POINT_TYPE, CITIES } from '../const.js'; import { formatEventDate, isElementHas } from '../util.js'; -import AbstractView from '../framework/view/abstract-view.js'; +import AbstractStatefulView from '../framework/view/abstract-stateful-view.js'; const DATE_FORMAT = 'DD/MM/YY HH:mm'; -function createEditablePointTemplate(point, destination, offer) { - const type = point.type; +function createEditablePointTemplate(state) { + const type = state.type; return( `
  • @@ -29,20 +29,18 @@ function createEditablePointTemplate(point, destination, offer) { - + - - - + ${createDestinationsList()}
    - + - +
    @@ -50,7 +48,7 @@ function createEditablePointTemplate(point, destination, offer) { Price € - +
    @@ -60,20 +58,20 @@ function createEditablePointTemplate(point, destination, offer) {
    - ${isElementHas(offer.offers) ? `
    + ${state.isOffers ? `

    Offers

    - ${createOffersList(offer)}` : ''} + ${createOffersList(state.offer, state.point.offers)}` : ''}
    - ${(isElementHas(destination.description) || - isElementHas(destination.pictures)) ? `
    + ${state.isDestination || + state.isPictures ? `

    Destination

    ` : ''} - ${isElementHas(destination.description) ? `

    ${destination.description}

    ` : ''} - ${isElementHas(destination.pictures) ? `
    -
    ${createDestinationPhotosList(destination.pictures)}
    ` : ''} + ${state.isDestination ? `

    ${state.destination?.description}

    ` : ''} + ${state.isPictures ? `
    +
    ${createDestinationPhotosList(state.destination?.pictures)}
    ` : ''}
    @@ -81,12 +79,12 @@ function createEditablePointTemplate(point, destination, offer) { ); } -function createDestinationPhotosList(pictures){ +function createDestinationPhotosList(pictures) { const photosList = pictures.map((picture) => `${picture.description}`); return photosList.join(''); } -function createEventTypeList(type){ +function createEventTypeList(type) { const eventTypeList = POINT_TYPE.map((pointType) => `
    @@ -94,12 +92,18 @@ function createEventTypeList(type){ return eventTypeList.join(''); } -function createOffersList(offer){ +function createDestinationsList() { + const destinationsList = CITIES.map((city) => ``); + return destinationsList.join(''); +} + +function createOffersList(offer, pointOffers) { const offerList = offer.offers.map((offerItem) => { const offerName = offerItem.title.replace(' ', '').toLowerCase(); + const isCheked = pointOffers.find((id) => id === offerItem.id) !== undefined; return `
    - +
  • ` : '';}); return offersList.join(''); } - export default class PointView extends AbstractView{ #point = null; #city = null;