diff --git a/src/const.js b/src/const.js index 8fac4b6..528fc9f 100644 --- a/src/const.js +++ b/src/const.js @@ -79,6 +79,14 @@ const SortType = { OFFERS: 'offers' }; +const EnabledSortType = { + [SortType.DAY]: true, + [SortType.EVENT]: false, + [SortType.TIME]: true, + [SortType.PRICE]: true, + [SortType.OFFERS]: false +}; + export { OFFER_COUNT, DESTINATION_COUNT, @@ -92,5 +100,6 @@ export { POINT_EMPTY, FilterType, Mode, - SortType + SortType, + EnabledSortType } diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index 7fb1d33..68b80d5 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -2,8 +2,10 @@ import SortView from '../view/sort-view.js'; import TripView from '../view/point-list-view.js'; import EmptyListView from '../view/empty-list-view.js'; import PointPresenter from './point-presenter.js'; -import { render, replace } from '../framework/render.js'; +import { render, replace, remove } from '../framework/render.js'; import { updateItem } from '../utils.js'; +import { SortType, EnabledSortType } from '../const.js'; +import { sort } from '../utils/sort.js'; import PointListView from '../view/point-list-view.js'; export default class TripPresenter { @@ -12,10 +14,12 @@ export default class TripPresenter { #offersModel = null; #pointsModel = null; #pointListComponent = new TripView(); - #sortComponent = new SortView(); + #sortComponent = null; #points = []; + #currentSortType = SortType.DAY; + #pointPresenters = new Map(); constructor({ tripContainer, destinationsModel, offersModel, pointsModel }) { @@ -23,7 +27,8 @@ export default class TripPresenter { this.#destinationsModel = destinationsModel; this.#offersModel = offersModel; this.#pointsModel = pointsModel; - this.#points = [...this.#pointsModel.get()]; + + this.#points = sort[SortType.DAY]([...this.#pointsModel.get()]); } init() { @@ -44,6 +49,11 @@ export default class TripPresenter { this.#pointPresenters.set(point.id, pointPresenter); } + #sortPoints = (sortType) => { + this.#currentSortType = sortType; + this.#points = sort[this.#currentSortType](this.#points); + } + #renderPoints = () => { this.#points.forEach((point) => { this.#renderPoint(point); @@ -55,6 +65,22 @@ export default class TripPresenter { this.#pointPresenters.clear(); } + #renderSort = () => { + const prevSortComponent = this.#sortComponent; + + this.#sortComponent = new SortView({ + sortType: this.#currentSortType, + onItemChange: this.#sortTypeChangeHandler + }); + + if (prevSortComponent) { + replace(this.#sortComponent, prevSortComponent); + remove(prevSortComponent); + } else { + render(this.#sortComponent, this.#tripContainer); + } + } + #renderPointContainer = () => { this.#pointListComponent = new PointListView(); render(this.#pointListComponent, this.#tripContainer); @@ -66,6 +92,7 @@ export default class TripPresenter { return; } + this.#renderSort(); this.#renderPointContainer(); this.#renderPoints(); }; @@ -78,4 +105,11 @@ export default class TripPresenter { #modeChangeHandler = () => { this.#pointPresenters.forEach((presenter) => presenter.resetView()); }; + + #sortTypeChangeHandler = (sortType) => { + this.#sortPoints(sortType); + this.#clearPoints(); + this.#renderSort(); + this.#renderPoints(); + }; } diff --git a/src/utils.js b/src/utils.js index 1bee450..a185b19 100644 --- a/src/utils.js +++ b/src/utils.js @@ -102,6 +102,21 @@ function updateItem(items, update) { return items.map((item) => item.id === update.id ? update : item); } +function getPointsDateDifference(pointA, pointB) { + return new Date(pointA.dateFrom) - new Date(pointB.dateFrom); +} + +function getPointsPriceDifference(pointA, pointB) { + return pointB.basePrice - pointA.basePrice; +} + +function getPointsDurationDifference(pointA, pointB) { + const durationA = new Date(pointA.dateTo) - new Date(pointA.dateFrom); + const durationB = new Date(pointB.dateTo) - new Date(pointB.dateFrom); + + return durationB - durationA; +} + export { getDate, getRandomInteger, @@ -114,5 +129,8 @@ export { isPointFuture, isPointPast, isPointPresent, - updateItem + updateItem, + getPointsDateDifference, + getPointsPriceDifference, + getPointsDurationDifference } diff --git a/src/utils/sort.js b/src/utils/sort.js new file mode 100644 index 0000000..1fd114b --- /dev/null +++ b/src/utils/sort.js @@ -0,0 +1,16 @@ +import { SortType } from '../const.js'; +import { getPointsDateDifference, getPointsDurationDifference, getPointsPriceDifference } from '../utils.js'; + +const sort = { + [SortType.DAY]: (points) => points.sort(getPointsDateDifference), + [SortType.PRICE]: (points) => points.sort(getPointsPriceDifference), + [SortType.TIME]: (points) => points.sort(getPointsDurationDifference), + [SortType.EVENT]: () => { + throw new Error(`Sort by ${SortType.EVENT} is not implemented`); + }, + [SortType.OFFERS]: () => { + throw new Error(`Sort by ${SortType.OFFERS} is not implemented`); + } +}; + +export { sort }; diff --git a/src/view/sort-view.js b/src/view/sort-view.js index 0f71640..f96624e 100644 --- a/src/view/sort-view.js +++ b/src/view/sort-view.js @@ -1,35 +1,64 @@ import AbstractView from '../framework/view/abstract-view.js'; +import { EnabledSortType, SortType } from '../const.js'; -const createSortTemplate = () => { +const createSortItemsTemplate = ({ items }) => { + const sortItems = items.map(sortItem => { + return ( + `
+ + +
` + ) + }).join(''); + + return sortItems; +} + +const createSortTemplate = ({ items }) => { return ( `
-
- - -
- -
- - -
-
- - -
-
- - -
-
- - -
-
` + ${createSortItemsTemplate({ items })} + ` ); -}; +} export default class SortView extends AbstractView { + #items = null; + #onItemChange = null; + + constructor({ sortType, onItemChange }) { + super(); + + this.#items = Object.values(SortType).map((type) => ({ + type, + isChecked: (type === sortType), + isDisabled: !EnabledSortType[type] + })); + + this.#onItemChange = onItemChange; + + this.element.addEventListener('change', this.#itemChangeHandler); + } + get template() { - return createSortTemplate(); + return createSortTemplate({ + items: this.#items + }); } + + #itemChangeHandler = (evt) => { + evt.preventDefault(); + this.#onItemChange(evt.target.dataset.sortType); + }; }