From e1a4e8175449bf2854808d9a1d201327d427e374 Mon Sep 17 00:00:00 2001 From: Voyage Date: Thu, 10 Oct 2024 18:01:57 +0500 Subject: [PATCH 1/5] Update filters-presenter.js --- src/presenter/filters-presenter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/presenter/filters-presenter.js b/src/presenter/filters-presenter.js index 5905f84..1f18112 100644 --- a/src/presenter/filters-presenter.js +++ b/src/presenter/filters-presenter.js @@ -28,4 +28,5 @@ export default class FiltersPresenter { items: this.#filters }), filtersContainer); } + } From 6f30d556424960376a9661cf9c3db4cf9ba89a7e Mon Sep 17 00:00:00 2001 From: Voyage Date: Thu, 10 Oct 2024 18:01:59 +0500 Subject: [PATCH 2/5] Update point-presenter.js --- src/presenter/point-presenter.js | 71 ++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js index 22f27ef..0994f10 100644 --- a/src/presenter/point-presenter.js +++ b/src/presenter/point-presenter.js @@ -9,34 +9,31 @@ export default class PointPresenter { #pointEditorComponent = null; #point = null; #onPointChange = null; + #onEditorOpen = null; #destinationsModel = null; #offersModel = null; #mode = PointMode.IDLE; - constructor({ container, destinationsModel, offersModel, onPointChange }) { + constructor({ + container, + destinationsModel, + offersModel, + onPointChange, + onEditorOpen, + }) { this.#container = container; this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; this.#onPointChange = onPointChange; + this.#onEditorOpen = onEditorOpen; } init(point) { this.#point = point; - this.#pointComponent = new PointView({ - point: this.#point, - destination: this.#destinationsModel.getById(point.destination), - offers: this.#offersModel.getByType(point.type), - onEditClick: this.#pointEditHandler, - }); + this.#pointComponent = this.#createPointView(); - this.#pointEditorComponent = new PointEditorView({ - point: this.#point, - destination: this.#destinationsModel.getById(point.destination), - offers: this.#offersModel.getByType(point.type), - onCloseClick: this.#pointCloseHandler, - onSubmitForm: this.#pointSubmitHandler, - }); + this.#pointEditorComponent = this.#createPointEditorView(); if (this.#mode === PointMode.EDITABLE) { render(this.#pointEditorComponent, this.#container); @@ -49,20 +46,9 @@ export default class PointPresenter { update(point) { this.#point = point; - const updatedPointComponent = new PointView({ - point: this.#point, - destination: this.#destinationsModel.getById(point.destination), - offers: this.#offersModel.getByType(point.type), - onEditClick: this.#pointEditHandler, - }); + const updatedPointComponent = this.#createPointView(); - const updatedEditorComponent = new PointEditorView({ - point: this.#point, - destination: this.#destinationsModel.getById(point.destination), - offers: this.#offersModel.getByType(point.type), - onCloseClick: this.#pointCloseHandler, - onSubmitForm: this.#pointSubmitHandler, - }); + const updatedEditorComponent = this.#createPointEditorView(); if (this.#mode === PointMode.EDITABLE) { replace(updatedEditorComponent, this.#pointEditorComponent); @@ -79,6 +65,32 @@ export default class PointPresenter { remove(this.#pointEditorComponent); } + resetView() { + if (this.#mode !== PointMode.IDLE) { + this.#replaceEditorByPoint(); + } + } + + #createPointView() { + return new PointView({ + point: this.#point, + destination: this.#destinationsModel.getById(this.#point.destination), + offers: this.#offersModel.getByType(this.#point.type), + onEditClick: this.#pointEditHandler, + onFavoriteToggle: this.#pointFavoriteToggleHandler, + }); + } + + #createPointEditorView() { + return new PointEditorView({ + point: this.#point, + destinations: this.#destinationsModel.get(), + offers: this.#offersModel.get(), + onCloseClick: this.#pointCloseHandler, + onSubmitForm: this.#pointSubmitHandler, + }); + } + #replacePointByEditor() { replace(this.#pointEditorComponent, this.#pointComponent); document.addEventListener('keydown', this.#escKeyDownHandler); @@ -99,6 +111,7 @@ export default class PointPresenter { }; #pointEditHandler = () => { + this.#onEditorOpen(); this.#replacePointByEditor(); }; @@ -110,4 +123,8 @@ export default class PointPresenter { #pointCloseHandler = () => { this.#replaceEditorByPoint(); }; + + #pointFavoriteToggleHandler = (isFavorite) => { + this.#onPointChange({ ...this.#point, isFavorite }); + }; } From 3ffa8cf3b8321e4fd15bc54ea53daade1858784d Mon Sep 17 00:00:00 2001 From: Voyage Date: Thu, 10 Oct 2024 18:02:00 +0500 Subject: [PATCH 3/5] Update route-presenter.js --- src/presenter/route-presenter.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/presenter/route-presenter.js b/src/presenter/route-presenter.js index 8105ab4..101e740 100644 --- a/src/presenter/route-presenter.js +++ b/src/presenter/route-presenter.js @@ -1,4 +1,7 @@ -import { remove, render } from '../framework/render.js'; +import { + remove, + render, +} from '../framework/render.js'; import EventsListView from '../view/events-list-view.js'; import EventsListEmptyView from '../view/events-list-empty-view.js'; import { SORTING_COLUMNS, SortType } from '../const.js'; @@ -17,14 +20,17 @@ export default class RoutePresenter { #sortingComponent = null; #pointsPresenters = new Map(); - constructor({ container, pointsModel, offersModel, destinationsModel }) { + constructor({ + container, + pointsModel, + offersModel, + destinationsModel + }) { this.#container = container; this.#pointsModel = pointsModel; this.#offersModel = offersModel; this.#destinationsModel = destinationsModel; - this.#points = sortByType[this.#currentSortType]([ - ...this.#pointsModel.get(), - ]); + this.#points = sortByType[this.#currentSortType]([...this.#pointsModel.get()]); } init() { @@ -75,12 +81,17 @@ export default class RoutePresenter { destinationsModel: this.#destinationsModel, offersModel: this.#offersModel, onPointChange: this.#pointChangeHandler, + onEditorOpen: this.#pointEditHandler, }); pointPresenter.init(point); this.#pointsPresenters.set(point.id, pointPresenter); } + #pointEditHandler = () => { + this.#pointsPresenters.forEach((presenter) => presenter.resetView()); + }; + #pointChangeHandler = (updatedPoint) => { this.#points = updateItem(this.#points, updatedPoint); this.#pointsPresenters.get(updatedPoint.id).update(updatedPoint); From 373a17570f4aebde3266f767bfcd5223f7ab7168 Mon Sep 17 00:00:00 2001 From: Voyage Date: Thu, 10 Oct 2024 18:02:02 +0500 Subject: [PATCH 4/5] Update point-editor-view.js --- src/view/point-editor-view.js | 167 ++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 57 deletions(-) diff --git a/src/view/point-editor-view.js b/src/view/point-editor-view.js index 215f142..e089ebc 100644 --- a/src/view/point-editor-view.js +++ b/src/view/point-editor-view.js @@ -1,34 +1,43 @@ -import AbstractView from '../framework/view/abstract-view.js'; +import AbstractStatefulView from '../framework/view/abstract-stateful-view.js'; +import { EVENT_TYPES, CITIES, DateFormat } from '../const.js'; +import { toCapitalize, formatDate } from '../utils.js'; -import { - EVENT_TYPES, - CITIES, - DateFormat -} from '../const.js'; - -import { - toCapitalize, - formatDate -} from '../utils.js'; - -const createEventTypeTemplate = (types, currentType) => types.reduce((markup, type)=>`${markup} +const createEventTypeTemplate = (types, currentType) => + types.reduce( + (markup, type) => `${markup}
- - -
`, ''); - -const createCitiesTemplate = (cities) => cities.reduce((markup, city)=>`${markup}`, ''); + + + `, + '' + ); + +const createCitiesTemplate = (cities) => + cities.reduce( + (markup, city) => + `${markup}`, + '' + ); const createOffersTemplate = (offers, pointOffers) => { - const items = offers.reduce((markup, {id, title, price})=>`${markup} + const items = offers.reduce( + (markup, { id, title, price }) => `${markup}
- offer === id) ? 'checked' : ''}> -
`, ''); + `, + '' + ); if (offers.length > 0) { return `
@@ -44,8 +53,11 @@ const createOffersTemplate = (offers, pointOffers) => { }; const createDestinationPhotosTemplate = (destination) => { - const photos = destination.pictures.reduce((markup, {src, description})=>`${markup} - ${description}`, ''); + const photos = destination.pictures.reduce( + (markup, { src, description }) => `${markup} + ${description}`, + '' + ); if (destination.pictures.length > 0) { return ` @@ -60,18 +72,8 @@ const createDestinationPhotosTemplate = (destination) => { } }; -function createPointEditorTemplate({ - point, - pointDestination, - pointOffers -}) { - const { - type, - basePrice, - dateFrom, - dateTo, - offers - } = point; +function createPointEditorTemplate({ point, pointDestination, pointOffers }) { + const { type, basePrice, dateFrom, dateTo, offers } = point; return `
  • @@ -94,7 +96,9 @@ function createPointEditorTemplate({ - + ${createCitiesTemplate(CITIES)} @@ -102,10 +106,16 @@ function createPointEditorTemplate({
    - + - +
    @@ -126,7 +136,9 @@ function createPointEditorTemplate({ ${createOffersTemplate(pointOffers, offers)}

    Destination

    -

    ${pointDestination.description}

    +

    ${ + pointDestination.description +}

    ${createDestinationPhotosTemplate(pointDestination)}
    @@ -135,36 +147,49 @@ function createPointEditorTemplate({
  • `; } - -export default class PointEditorView extends AbstractView { +export default class PointEditorView extends AbstractStatefulView { #point = null; - #destination = null; + #destinations = null; #offers = null; #onCloseClick = null; #onSubmitForm = null; - constructor({ - point, - destination, - offers, - onCloseClick, - onSubmitForm - }) { + constructor({ point, destinations, offers, onCloseClick, onSubmitForm }) { super(); this.#point = point; - this.#destination = destination; + this.#destinations = destinations; this.#offers = offers; this.#onCloseClick = onCloseClick; this.#onSubmitForm = onSubmitForm; - this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#closeClickHandler); - this.element.querySelector('.event.event--edit').addEventListener('submit', this.#saveClickHandler); + + this._setState(this.#point); + this._restoreHandlers(); + } + + _restoreHandlers() { + this.element + .querySelector('.event__rollup-btn') + .addEventListener('click', this.#closeClickHandler); + this.element + .querySelector('.event.event--edit') + .addEventListener('submit', this.#saveClickHandler); + this.element + .querySelector('.event__type-group') + .addEventListener('change', this.#eventTypeChangeHandler); + this.element + .querySelector('.event__input--destination') + .addEventListener('change', this.#destinationChangeHandler); + this.element.querySelector('.event__available-offers')?.addEventListener('change', this.#offersChangeHandler); } get template() { return createPointEditorTemplate({ - point: this.#point, - pointDestination: this.#destination, - pointOffers: this.#offers + point: this._state, + pointDestination: this.#destinations.find( + ({ id }) => id === this._state.destination + ), + pointOffers: this.#offers.find(({ type }) => type === this._state.type) + .offers, }); } @@ -175,6 +200,34 @@ export default class PointEditorView extends AbstractView { #saveClickHandler = (evt) => { evt.preventDefault(); - this.#onSubmitForm(); + this.#onSubmitForm(this._state); + }; + + #eventTypeChangeHandler = (evt) => { + this.#updatePoint('type', evt.target.value); + }; + + #destinationChangeHandler = (evt) => { + const currentDestination = this.#destinations.find( + (pointDestination) => pointDestination.name === evt.target.value + ); + const currentDestinationId = currentDestination + ? currentDestination.id + : this._state.destination; + + this.#updatePoint('destination', currentDestinationId); + }; + + #offersChangeHandler = () => { + const checkedOffers = Array.from(this.element.querySelectorAll('.event__offer-checkbox:checked')); + this.#updatePoint('offers', checkedOffers.map((offer) => offer.id), true); + }; + + #updatePoint = (key, value, skipRerender = false) => { + if (skipRerender) { + this._setState({ ...this._state, [key]: value }); + } else { + this.updateElement({ ...this._state, [key]: value }); + } }; } From 1d731cb46a467740c836a1375e69e3b479186021 Mon Sep 17 00:00:00 2001 From: Voyage Date: Thu, 10 Oct 2024 18:02:04 +0500 Subject: [PATCH 5/5] Update point-view.js --- src/view/point-view.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/view/point-view.js b/src/view/point-view.js index 002a5fa..8c1bf59 100644 --- a/src/view/point-view.js +++ b/src/view/point-view.js @@ -73,19 +73,23 @@ export default class PointView extends AbstractView { #destination = null; #offers = null; #onEditClick = null; + #onFavoriteToggle = null; constructor({ point, offers, destination, onEditClick, + onFavoriteToggle, }) { super(); this.#eventPoint = point; this.#offers = offers; this.#destination = destination; this.#onEditClick = onEditClick; + this.#onFavoriteToggle = onFavoriteToggle; this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#editClickHandler); + this.element.querySelector('.event__favorite-btn').addEventListener('click', this.#favoriteToggleHandler); } get template() { @@ -97,4 +101,9 @@ export default class PointView extends AbstractView { evt.preventDefault(); this.#onEditClick(); }; + + #favoriteToggleHandler = (evt) => { + evt.preventDefault(); + this.#onFavoriteToggle(!this.#eventPoint.isFavorite); + }; }