diff --git a/src/main.js b/src/main.js index 96693b7..1d68430 100644 --- a/src/main.js +++ b/src/main.js @@ -2,16 +2,14 @@ import { render } from './framework/render.js'; import DataInfoTrip from './view/data-info-view.js'; import TripPresenter from './presenter/trip-presenter.js'; import PointsModel from './model/point-model.js'; - - const pointsContainer = document.querySelector('.trip-events'); -const tripMain = document.querySelector('.trip-main'); +const pointsModel = new PointsModel(); +const tripMain = document.querySelector('.trip-main'); render(new DataInfoTrip(), tripMain, 'afterbegin'); -const pointsModel = new PointsModel(); -const createNewPoint = new TripPresenter({pointsContainer: pointsContainer, pointsModel}); +const createNewPoint = new TripPresenter({pointsContainer, pointsModel}); createNewPoint.init(); diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js new file mode 100644 index 0000000..69db42a --- /dev/null +++ b/src/presenter/point-presenter.js @@ -0,0 +1,93 @@ +import NewPointView from '../view/point-view.js'; +import EditFormView from '../view/edit-form-view.js'; +import { render, replace, remove } from '../framework/render.js'; + +const Mode = { + DEFAULT: 'DEFAULT', + EDITING: 'EDITING', +}; +export default class PointPresenter { + + #handleModeChange = null; + #mode = Mode.DEFAULT; + + constructor(point, boardOffers, boardDestinations, containerPointsView, onModeChange) { + this.point = point; + this.boardOffers = boardOffers; + this.boardDestinations = boardDestinations; + this.containerPointsView = containerPointsView; + this.#handleModeChange = onModeChange; + } + + #createPoint() { + this.pointView = new NewPointView({ + points: this.point, + offers: this.boardOffers, + destinations: this.boardDestinations, + }); + } + + #createEditPoint() { + this.editPointView = new EditFormView({ + points: this.point, + offers: this.boardOffers, + destinations: this.boardDestinations, + }); + } + + #openEditPoint() { + this.pointView.setListenerClick(() => this.replaceCardToForm()); + this.pointView.getListenerClick(); + } + + #closeEditPoint() { + this.editPointView.setListenerClick(() => this.replaceFormToCard()); + this.editPointView.getListenerClick(); + } + + replaceCardToForm() { + replace(this.editPointView, this.pointView); + window.addEventListener('keydown', this.#handlerEsc); + this.#handleModeChange(); + this.#mode = Mode.EDITING; + } + + replaceFormToCard() { + replace(this.pointView, this.editPointView); + window.removeEventListener('keydown', this.#handlerEsc); + this.#mode = Mode.DEFAULT; + } + + resetView() { + if (this.#mode !== Mode.DEFAULT) { + this.replaceFormToCard(); + } + } + + #handlerEsc = (evt) => { + if (evt.key === 'Escape') { + evt.preventDefault(); + this.replaceFormToCard(); + } + }; + + #drawPoint() { + render(this.pointView, this.containerPointsView.element); + } + + destroy() { + remove(this.pointView); + remove(this.editPointView); + } + + + init() { + this.#createPoint(); + this.#createEditPoint(); + this.#drawPoint(); + this.#closeEditPoint(); + this.#openEditPoint(); + + } + +} diff --git a/src/presenter/points-presenter.js b/src/presenter/points-presenter.js new file mode 100644 index 0000000..97584e0 --- /dev/null +++ b/src/presenter/points-presenter.js @@ -0,0 +1,110 @@ +import { render, remove } from '../framework/render.js'; +import NewSortView from '../view/sort-view.js'; +import ContainerPointsView from '../view/container-points-view.js'; +import FiltersTitleView from '../view/filters-title-view.js'; +import { getDifferencesDates } from '../utils.js'; +import PointPresenter from './point-presenter.js'; + + +const tripFilters = document.querySelector('.trip-controls__filters'); + +export default class PointsPresenter { + containerPointsView = new ContainerPointsView(); + sort = new NewSortView(); + filtersTitle = new FiltersTitleView(); + activeFilter = 'everything'; + activeSort = 'sort-day'; + #points = new Set(); + + constructor(pointsContainer, pointsModel) { + this.pointsContainer = pointsContainer; + this.pointsModel = pointsModel; + } + + get pointsData() { + return this.pointsModel.getPoints(); + } + + get offers() { + return this.pointsModel.getOffers(); + } + + get destinations() { + return this.pointsModel.getDestinations(); + } + + get filteredPoints() { + switch(this.activeFilter) { + case 'future': + return this.pointsData.filter((pointData) => new Date(pointData.dateFrom) < new Date()); + case 'everything': + return this.pointsData; + case 'present': + return this.pointsData.filter((pointData) => new Date(pointData.dateFrom) === new Date()); + case 'past': + return this.pointsData.filter((pointData) => new Date(pointData.dateFrom) > new Date()); + } + } + + get sortedPoints() { + switch (this.activeSort) { + case 'sort-day': + return this.filteredPoints.sort((a,b) => b.dateFrom > a.dateFrom ? 1 : -1); + case 'sort-time': + return this.filteredPoints.sort((a,b) => getDifferencesDates(b.dateTo, b.dateFrom) > getDifferencesDates(a.dateTo, a.dateFrom) ? 1 : -1); + case 'sort-price': + return this.filteredPoints.sort((a,b) => b.basePrice > a.basePrice ? 1 : -1); + } + } + + #renderPoint(point) { + const pointPresenter = new PointPresenter(point, this.offers, this.destinations, this.containerPointsView, this.#handleModeChange); + this.#points.add(pointPresenter); + } + + destroyAllPoints() { + this.#points.forEach((pointPresenter) => { + pointPresenter.destroy(); + }); + this.#points.clear(); + } + + #handleModeChange = () => { + this.#points.forEach((pointPresenter) => pointPresenter.resetView()); + }; + + #redrawPoints() { + this.destroyAllPoints(); + this.sortedPoints.forEach((pointData) => { + this.#renderPoint(pointData); + }); + this.#points.forEach((pointPresenter) => { + pointPresenter.init(); + }); + } + + onClickFilterButtons = (evt) => { + this.activeFilter = evt.target.value; + this.#redrawPoints(); + }; + + onClickSortButtons = (evt) => { + this.activeSort = evt.target.value; + this.#redrawPoints(); + }; + + + init() { + + render(this.filtersTitle, tripFilters); + this.filtersTitle.getListenerFilters(this.onClickFilterButtons); + + render(this.sort, this.pointsContainer); + this.sort.getListenerSort(this.onClickSortButtons); + + render(this.containerPointsView, this.pointsContainer); + + this.#redrawPoints(); + + } +} diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index 650ad54..0b68a75 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -1,17 +1,5 @@ -import { render, replace, remove } from '../framework/render.js'; -import NewSortView from '../view/sort-view.js'; -import ContainerPointsView from '../view/container-points-view.js'; -import NewPointView from '../view/point-view.js'; -import EditFormView from '../view/edit-form-view.js'; -import FiltersTitleView from '../view/filters-title-view.js'; -import { getDifferencesDates, compareNumbers } from '../utils.js'; - - -const tripFilters = document.querySelector('.trip-controls__filters'); +import PointsPresenter from './points-presenter.js'; export default class TripPresenter { - containerPointsView = new ContainerPointsView(); - sort = new NewSortView(); - filtersTitle = new FiltersTitleView(); constructor({pointsContainer, pointsModel}) { this.pointsContainer = pointsContainer; @@ -19,105 +7,7 @@ export default class TripPresenter { } init() { - - this.boardPoints = [...this.pointsModel.getPoints()]; - this.boardOffers = this.pointsModel.getOffers(); - this.boardDestinations = this.pointsModel.getDestinations(); - this.activeFilter = this.boardPoints; - - const deleteAllPoints = () => { - document.querySelectorAll('.trip-events__item').forEach((point) => point.remove()); - document.querySelectorAll('.event--edit').forEach((editPoint) => editPoint.remove()); - }; - - const redrawPoints = (boardPoints) => { - deleteAllPoints(); - for(let i = 0; i < boardPoints.length; i++) { - const pointView = new NewPointView({ - points: boardPoints[i], - offers: this.boardOffers, - destinations: this.boardDestinations, - }); - - const editPointView = new EditFormView({ - points: boardPoints[i], - offers: this.boardOffers, - destinations: this.boardDestinations, - }); - render(pointView, this.containerPointsView.element); - - - const handlerEsc = (evt) => { - if (evt.key === 'Escape') { - if (editPointView) { - replace(pointView, editPointView); - } - } - window.removeEventListener('keydown', handlerEsc); - }; - - pointView.setListenerClick(() => { - replace(editPointView, pointView); - window.addEventListener('keydown', handlerEsc); - }); - pointView.getListenerClick(); - - editPointView.setListenerClick(() => { - replace(pointView, editPointView); - window.removeEventListener('keydown', handlerEsc); - }); - editPointView.getListenerClick(); - - } - }; - - - const detectClickOnFilter = () => { - if (this.filtersTitle.element.querySelector('#filter-future').checked) { - const boardPointsFuture = this.boardPoints.filter((point) => point.dateFrom < new Date().toISOString()); - redrawPoints(boardPointsFuture); - this.activeFilter = boardPointsFuture; - } - if (this.filtersTitle.element.querySelector('#filter-everything').checked) { - redrawPoints(this.boardPoints); - this.activeFilter = this.boardPoints; - } - if (this.filtersTitle.element.querySelector('#filter-present').checked) { - const boardPointsPresent = this.boardPoints.filter((point) => point.dateFrom === new Date().toISOString()); - redrawPoints(boardPointsPresent); - this.activeFilter = boardPointsPresent; - } - if (this.filtersTitle.element.querySelector('#filter-past').checked) { - const boardPointsPast = this.boardPoints.filter((point) => point.dateFrom > new Date().toISOString()); - redrawPoints(boardPointsPast); - this.activeFilter = boardPointsPast; - } - }; - - const detectClickOnSort = () => { - if (this.sort.element.querySelector('#sort-day').checked) { - const boardPointsSortDay = this.activeFilter.sort((a, b) => b.dateFrom > a.dateFrom ? 1 : -1); - redrawPoints(boardPointsSortDay); - } - if (this.sort.element.querySelector('#sort-time').checked) { - const boardPointsSortDay = this.activeFilter.sort((a, b) => getDifferencesDates(b.dateFrom, b.dateTo) > getDifferencesDates(a.dateFrom, a.dateTo) ? 1 : -1); - redrawPoints(boardPointsSortDay); - } - if (this.sort.element.querySelector('#sort-price').checked) { - const boardPointsSortDay = this.activeFilter.sort((a, b) => b.basePrice > a.basePrice ? 1 : -1); - redrawPoints(boardPointsSortDay); - } - }; - - render(this.filtersTitle, tripFilters); - this.filtersTitle.getListenerFilters(detectClickOnFilter); - - render(this.sort, this.pointsContainer); - this.sort.getListenerSort(detectClickOnSort); - - render(this.containerPointsView, this.pointsContainer); - - redrawPoints(this.boardPoints.sort((a, b) => b.dateFrom > a.dateFrom ? 1 : -1)); - + const pointsPresenter = new PointsPresenter(this.pointsContainer, this.pointsModel); + pointsPresenter.init(); } } diff --git a/src/view/point-view.js b/src/view/point-view.js index 5dd8c2d..488223b 100644 --- a/src/view/point-view.js +++ b/src/view/point-view.js @@ -74,5 +74,13 @@ export default class NewPointView extends AbstractView{ this.element.querySelector('.event__rollup-btn').addEventListener('click', this.onButtonClick); } + setListenerFavorite(checkFavorite) { + this.checkFavorite = checkFavorite; + } + + getListenerFavorite() { + this.element.querySelector('.event__favorite-btn').addEventListener('click', this.checkFavorite); + } + }